Extend event effects through add-building strip
This commit is contained in:
parent
4945430149
commit
b2da02befa
7 changed files with 3319 additions and 1161 deletions
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"descriptor_count": 520,
|
"descriptor_count": 614,
|
||||||
"raw_table_binary_sha256": "01b0d2496cddefd80e7e8678930e00b13eb8607dd4960096f527564f02af36d4",
|
"raw_table_binary_sha256": "9e96b0695cb722a700f99c8dce498d34da7235e562b1e275bcc1764f8c9b7eb1",
|
||||||
"semantic_catalog_version": 1,
|
"semantic_catalog_version": 1,
|
||||||
"descriptors": [
|
"descriptors": [
|
||||||
{
|
{
|
||||||
|
|
@ -2175,7 +2175,7 @@
|
||||||
{
|
{
|
||||||
"descriptor_id": 241,
|
"descriptor_id": 241,
|
||||||
"label": "2-D-2 Availability",
|
"label": "2-D-2 Availability",
|
||||||
"target_mask_bits": 11,
|
"target_mask_bits": 15,
|
||||||
"parameter_family": "locomotive_availability_scalar",
|
"parameter_family": "locomotive_availability_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
"runtime_status": "executable",
|
"runtime_status": "executable",
|
||||||
|
|
@ -2184,7 +2184,7 @@
|
||||||
{
|
{
|
||||||
"descriptor_id": 242,
|
"descriptor_id": 242,
|
||||||
"label": "E-88 Availability",
|
"label": "E-88 Availability",
|
||||||
"target_mask_bits": 11,
|
"target_mask_bits": 15,
|
||||||
"parameter_family": "locomotive_availability_scalar",
|
"parameter_family": "locomotive_availability_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
"runtime_status": "executable",
|
"runtime_status": "executable",
|
||||||
|
|
@ -2193,7 +2193,7 @@
|
||||||
{
|
{
|
||||||
"descriptor_id": 243,
|
"descriptor_id": 243,
|
||||||
"label": "Adler 2-2-2 Availability",
|
"label": "Adler 2-2-2 Availability",
|
||||||
"target_mask_bits": 11,
|
"target_mask_bits": 15,
|
||||||
"parameter_family": "locomotive_availability_scalar",
|
"parameter_family": "locomotive_availability_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
"runtime_status": "executable",
|
"runtime_status": "executable",
|
||||||
|
|
@ -2202,7 +2202,7 @@
|
||||||
{
|
{
|
||||||
"descriptor_id": 244,
|
"descriptor_id": 244,
|
||||||
"label": "USA 103 Availability",
|
"label": "USA 103 Availability",
|
||||||
"target_mask_bits": 11,
|
"target_mask_bits": 15,
|
||||||
"parameter_family": "locomotive_availability_scalar",
|
"parameter_family": "locomotive_availability_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
"runtime_status": "executable",
|
"runtime_status": "executable",
|
||||||
|
|
@ -2211,7 +2211,7 @@
|
||||||
{
|
{
|
||||||
"descriptor_id": 245,
|
"descriptor_id": 245,
|
||||||
"label": "American 4-4-0 Availability",
|
"label": "American 4-4-0 Availability",
|
||||||
"target_mask_bits": 11,
|
"target_mask_bits": 15,
|
||||||
"parameter_family": "locomotive_availability_scalar",
|
"parameter_family": "locomotive_availability_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
"runtime_status": "executable",
|
"runtime_status": "executable",
|
||||||
|
|
@ -2220,7 +2220,7 @@
|
||||||
{
|
{
|
||||||
"descriptor_id": 246,
|
"descriptor_id": 246,
|
||||||
"label": "Atlantic 4-4-2 Availability",
|
"label": "Atlantic 4-4-2 Availability",
|
||||||
"target_mask_bits": 11,
|
"target_mask_bits": 15,
|
||||||
"parameter_family": "locomotive_availability_scalar",
|
"parameter_family": "locomotive_availability_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
"runtime_status": "executable",
|
"runtime_status": "executable",
|
||||||
|
|
@ -2229,7 +2229,7 @@
|
||||||
{
|
{
|
||||||
"descriptor_id": 247,
|
"descriptor_id": 247,
|
||||||
"label": "Baldwin 0-6-0 Availability",
|
"label": "Baldwin 0-6-0 Availability",
|
||||||
"target_mask_bits": 11,
|
"target_mask_bits": 15,
|
||||||
"parameter_family": "locomotive_availability_scalar",
|
"parameter_family": "locomotive_availability_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
"runtime_status": "executable",
|
"runtime_status": "executable",
|
||||||
|
|
@ -2238,7 +2238,7 @@
|
||||||
{
|
{
|
||||||
"descriptor_id": 248,
|
"descriptor_id": 248,
|
||||||
"label": "Be 5/7 Availability",
|
"label": "Be 5/7 Availability",
|
||||||
"target_mask_bits": 11,
|
"target_mask_bits": 15,
|
||||||
"parameter_family": "locomotive_availability_scalar",
|
"parameter_family": "locomotive_availability_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
"runtime_status": "executable",
|
"runtime_status": "executable",
|
||||||
|
|
@ -2247,7 +2247,7 @@
|
||||||
{
|
{
|
||||||
"descriptor_id": 249,
|
"descriptor_id": 249,
|
||||||
"label": "Beuth 2-2-2 Availability",
|
"label": "Beuth 2-2-2 Availability",
|
||||||
"target_mask_bits": 11,
|
"target_mask_bits": 15,
|
||||||
"parameter_family": "locomotive_availability_scalar",
|
"parameter_family": "locomotive_availability_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
"runtime_status": "executable",
|
"runtime_status": "executable",
|
||||||
|
|
@ -2256,7 +2256,7 @@
|
||||||
{
|
{
|
||||||
"descriptor_id": 250,
|
"descriptor_id": 250,
|
||||||
"label": "Big Boy 4-8-8-4 Availability",
|
"label": "Big Boy 4-8-8-4 Availability",
|
||||||
"target_mask_bits": 11,
|
"target_mask_bits": 15,
|
||||||
"parameter_family": "locomotive_availability_scalar",
|
"parameter_family": "locomotive_availability_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
"runtime_status": "executable",
|
"runtime_status": "executable",
|
||||||
|
|
@ -4682,6 +4682,852 @@
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
"runtime_status": "shell_owned",
|
"runtime_status": "shell_owned",
|
||||||
"executable_in_runtime": false
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 520,
|
||||||
|
"label": "Add Building Slot 18",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 521,
|
||||||
|
"label": "Add Building Slot 19",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 522,
|
||||||
|
"label": "Add Building Slot 20",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 523,
|
||||||
|
"label": "Add Building Slot 21",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 524,
|
||||||
|
"label": "Add Building Slot 22",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 525,
|
||||||
|
"label": "Add Building Slot 23",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 526,
|
||||||
|
"label": "Add Building Slot 24",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 527,
|
||||||
|
"label": "Add Building Slot 25",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 528,
|
||||||
|
"label": "Add Building Slot 26",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 529,
|
||||||
|
"label": "Add Building Slot 27",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 530,
|
||||||
|
"label": "Add Building Slot 28",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 531,
|
||||||
|
"label": "Add Building Slot 29",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 532,
|
||||||
|
"label": "Add Building Slot 30",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 533,
|
||||||
|
"label": "Add Building Slot 31",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 534,
|
||||||
|
"label": "Add Building Slot 32",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 535,
|
||||||
|
"label": "Add Building Slot 33",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 536,
|
||||||
|
"label": "Add Building Slot 34",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 537,
|
||||||
|
"label": "Add Building Slot 35",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 538,
|
||||||
|
"label": "Add Building Slot 36",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 539,
|
||||||
|
"label": "Add Building Slot 37",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 540,
|
||||||
|
"label": "Add Building Slot 38",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 541,
|
||||||
|
"label": "Add Building Slot 39",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 542,
|
||||||
|
"label": "Add Building Slot 40",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 543,
|
||||||
|
"label": "Add Building Slot 41",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 544,
|
||||||
|
"label": "Add Building Slot 42",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 545,
|
||||||
|
"label": "Add Building Slot 43",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 546,
|
||||||
|
"label": "Add Building Slot 44",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 547,
|
||||||
|
"label": "Add Building Slot 45",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 548,
|
||||||
|
"label": "Add Building Slot 46",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 549,
|
||||||
|
"label": "Add Building Slot 47",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 550,
|
||||||
|
"label": "Add Building Slot 48",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 551,
|
||||||
|
"label": "Add Building Slot 49",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 552,
|
||||||
|
"label": "Add Building Slot 50",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 553,
|
||||||
|
"label": "Add Building Slot 51",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 554,
|
||||||
|
"label": "Add Building Slot 52",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 555,
|
||||||
|
"label": "Add Building Slot 53",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 556,
|
||||||
|
"label": "Add Building Slot 54",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 557,
|
||||||
|
"label": "Add Building Slot 55",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 558,
|
||||||
|
"label": "Add Building Slot 56",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 559,
|
||||||
|
"label": "Add Building Slot 57",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 560,
|
||||||
|
"label": "Add Building Slot 58",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 561,
|
||||||
|
"label": "Add Building Slot 59",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 562,
|
||||||
|
"label": "Add Building Slot 60",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 563,
|
||||||
|
"label": "Add Building Slot 61",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 564,
|
||||||
|
"label": "Add Building Slot 62",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 565,
|
||||||
|
"label": "Add Building Slot 63",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 566,
|
||||||
|
"label": "Add Building Slot 64",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 567,
|
||||||
|
"label": "Add Building Slot 65",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 568,
|
||||||
|
"label": "Add Building Slot 66",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 569,
|
||||||
|
"label": "Add Building Slot 67",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 570,
|
||||||
|
"label": "Add Building Slot 68",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 571,
|
||||||
|
"label": "Add Building Slot 69",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 572,
|
||||||
|
"label": "Add Building Slot 70",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 573,
|
||||||
|
"label": "Add Building Slot 71",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 574,
|
||||||
|
"label": "Add Building Slot 72",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 575,
|
||||||
|
"label": "Add Building Slot 73",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 576,
|
||||||
|
"label": "Add Building Slot 74",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 577,
|
||||||
|
"label": "Add Building Slot 75",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 578,
|
||||||
|
"label": "Add Building Slot 76",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 579,
|
||||||
|
"label": "Add Building Slot 77",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 580,
|
||||||
|
"label": "Add Building Slot 78",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 581,
|
||||||
|
"label": "Add Building Slot 79",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 582,
|
||||||
|
"label": "Add Building Slot 80",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 583,
|
||||||
|
"label": "Add Building Slot 81",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 584,
|
||||||
|
"label": "Add Building Slot 82",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 585,
|
||||||
|
"label": "Add Building Slot 83",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 586,
|
||||||
|
"label": "Add Building Slot 84",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 587,
|
||||||
|
"label": "Add Building Slot 85",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 588,
|
||||||
|
"label": "Add Building Slot 86",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 589,
|
||||||
|
"label": "Add Building Slot 87",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 590,
|
||||||
|
"label": "Add Building Slot 88",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 591,
|
||||||
|
"label": "Add Building Slot 89",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 592,
|
||||||
|
"label": "Add Building Slot 90",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 593,
|
||||||
|
"label": "Add Building Slot 91",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 594,
|
||||||
|
"label": "Add Building Slot 92",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 595,
|
||||||
|
"label": "Add Building Slot 93",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 596,
|
||||||
|
"label": "Add Building Slot 94",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 597,
|
||||||
|
"label": "Add Building Slot 95",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 598,
|
||||||
|
"label": "Add Building Slot 96",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 599,
|
||||||
|
"label": "Add Building Slot 97",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 600,
|
||||||
|
"label": "Add Building Slot 98",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 601,
|
||||||
|
"label": "Add Building Slot 99",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 602,
|
||||||
|
"label": "Add Building Slot 100",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 603,
|
||||||
|
"label": "Add Building Slot 101",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 604,
|
||||||
|
"label": "Add Building Slot 102",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 605,
|
||||||
|
"label": "Add Building Slot 103",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 606,
|
||||||
|
"label": "Add Building Slot 104",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 607,
|
||||||
|
"label": "Add Building Slot 105",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 608,
|
||||||
|
"label": "Add Building Slot 106",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 609,
|
||||||
|
"label": "Add Building Slot 107",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 610,
|
||||||
|
"label": "Add Building Slot 108",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 611,
|
||||||
|
"label": "Add Building Slot 109",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 612,
|
||||||
|
"label": "Add Building Slot 110",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"descriptor_id": 613,
|
||||||
|
"label": "Add Building Slot 111",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "world_building_spawn",
|
||||||
|
"runtime_key": null,
|
||||||
|
"runtime_status": "shell_owned",
|
||||||
|
"executable_in_runtime": false
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -125,6 +125,9 @@ enum Command {
|
||||||
RuntimeInspectSmp {
|
RuntimeInspectSmp {
|
||||||
smp_path: PathBuf,
|
smp_path: PathBuf,
|
||||||
},
|
},
|
||||||
|
RuntimeInspectCompactEventDispatchCluster {
|
||||||
|
root_path: PathBuf,
|
||||||
|
},
|
||||||
RuntimeSummarizeSaveLoad {
|
RuntimeSummarizeSaveLoad {
|
||||||
smp_path: PathBuf,
|
smp_path: PathBuf,
|
||||||
},
|
},
|
||||||
|
|
@ -293,6 +296,51 @@ struct RuntimeSmpInspectionOutput {
|
||||||
inspection: SmpInspectionReport,
|
inspection: SmpInspectionReport,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize)]
|
||||||
|
struct RuntimeCompactEventDispatchClusterOutput {
|
||||||
|
root_path: String,
|
||||||
|
report: RuntimeCompactEventDispatchClusterReport,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize)]
|
||||||
|
struct RuntimeCompactEventDispatchClusterReport {
|
||||||
|
maps_scanned: usize,
|
||||||
|
maps_with_event_runtime_collection: usize,
|
||||||
|
maps_with_dispatch_strip_records: usize,
|
||||||
|
dispatch_strip_record_count: usize,
|
||||||
|
unknown_descriptor_ids: Vec<u32>,
|
||||||
|
unknown_descriptor_special_condition_label_matches: Vec<String>,
|
||||||
|
unknown_descriptor_occurrences:
|
||||||
|
BTreeMap<u32, Vec<RuntimeCompactEventDispatchClusterOccurrence>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize)]
|
||||||
|
struct RuntimeCompactEventDispatchClusterOccurrence {
|
||||||
|
path: String,
|
||||||
|
record_index: usize,
|
||||||
|
live_entry_id: u32,
|
||||||
|
payload_family: String,
|
||||||
|
signature_family: Option<String>,
|
||||||
|
condition_tuples: Vec<RuntimeCompactEventDispatchClusterConditionTuple>,
|
||||||
|
rows: Vec<RuntimeCompactEventDispatchClusterRow>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize)]
|
||||||
|
struct RuntimeCompactEventDispatchClusterConditionTuple {
|
||||||
|
raw_condition_id: i32,
|
||||||
|
subtype: u8,
|
||||||
|
metric: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize)]
|
||||||
|
struct RuntimeCompactEventDispatchClusterRow {
|
||||||
|
group_index: usize,
|
||||||
|
descriptor_id: u32,
|
||||||
|
descriptor_label: Option<String>,
|
||||||
|
opcode: u8,
|
||||||
|
raw_scalar_value: i32,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
#[derive(Debug, Serialize)]
|
||||||
struct RuntimeSaveLoadSummaryOutput {
|
struct RuntimeSaveLoadSummaryOutput {
|
||||||
path: String,
|
path: String,
|
||||||
|
|
@ -898,6 +946,9 @@ fn real_main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
Command::RuntimeInspectSmp { smp_path } => {
|
Command::RuntimeInspectSmp { smp_path } => {
|
||||||
run_runtime_inspect_smp(&smp_path)?;
|
run_runtime_inspect_smp(&smp_path)?;
|
||||||
}
|
}
|
||||||
|
Command::RuntimeInspectCompactEventDispatchCluster { root_path } => {
|
||||||
|
run_runtime_inspect_compact_event_dispatch_cluster(&root_path)?;
|
||||||
|
}
|
||||||
Command::RuntimeSummarizeSaveLoad { smp_path } => {
|
Command::RuntimeSummarizeSaveLoad { smp_path } => {
|
||||||
run_runtime_summarize_save_load(&smp_path)?;
|
run_runtime_summarize_save_load(&smp_path)?;
|
||||||
}
|
}
|
||||||
|
|
@ -1116,6 +1167,14 @@ fn parse_command() -> Result<Command, Box<dyn std::error::Error>> {
|
||||||
smp_path: PathBuf::from(path),
|
smp_path: PathBuf::from(path),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
[command, subcommand, root_path]
|
||||||
|
if command == "runtime"
|
||||||
|
&& subcommand == "inspect-compact-event-dispatch-cluster" =>
|
||||||
|
{
|
||||||
|
Ok(Command::RuntimeInspectCompactEventDispatchCluster {
|
||||||
|
root_path: PathBuf::from(root_path),
|
||||||
|
})
|
||||||
|
}
|
||||||
[command, subcommand, path]
|
[command, subcommand, path]
|
||||||
if command == "runtime" && subcommand == "summarize-save-load" =>
|
if command == "runtime" && subcommand == "summarize-save-load" =>
|
||||||
{
|
{
|
||||||
|
|
@ -1400,7 +1459,7 @@ fn parse_command() -> Result<Command, Box<dyn std::error::Error>> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
_ => Err(
|
_ => Err(
|
||||||
"usage: rrt-cli [validate [repo-root] | finance eval <snapshot.json> | finance diff <left.json> <right.json> | runtime validate-fixture <fixture.json> | runtime summarize-fixture <fixture.json> | runtime export-fixture-state <fixture.json> <snapshot.json> | runtime diff-state <left.json> <right.json> | runtime summarize-state <snapshot.json> | runtime import-state <input.json> <snapshot.json> | runtime inspect-smp <file.smp> | runtime summarize-save-load <file.smp> | runtime load-save-slice <file.smp> | runtime inspect-save-company-chairman <file.smp> | runtime inspect-save-placed-structure-triplets <file.smp> | runtime compare-region-fixed-row-runs <left.gms> <right.gms> | runtime inspect-periodic-company-service-trace <file.smp> | runtime inspect-region-service-trace <file.smp> | runtime inspect-infrastructure-asset-trace <file.smp> | runtime inspect-save-region-queued-notice-records <file.smp> | runtime inspect-placed-structure-dynamic-side-buffer <file.smp> | runtime inspect-unclassified-save-collections <file.smp> | runtime import-save-state <file.smp> <snapshot.json> | runtime export-save-slice <file.smp> <save-slice.json> | runtime export-overlay-import <snapshot.json> <save-slice.json> <overlay-import.json> | runtime inspect-pk4 <file.pk4> | runtime inspect-cargo-types <CargoTypes-dir> | runtime inspect-cargo-skins <Cargo106.PK4> | runtime inspect-cargo-economy-sources <CargoTypes-dir> <Cargo106.PK4> | runtime inspect-cargo-production-selector <CargoTypes-dir> <Cargo106.PK4> | runtime inspect-cargo-price-selector <CargoTypes-dir> <Cargo106.PK4> | runtime inspect-win <file.win> | runtime extract-pk4-entry <file.pk4> <entry-name> <output-path> | runtime inspect-campaign-exe <RT3.exe> | runtime compare-classic-profile <save1.gms> <save2.gms> [saveN.gms...] | runtime compare-105-profile <save1.gms> <save2.gms> [saveN.gms...] | runtime compare-candidate-table <file1> <file2> [fileN...] | runtime compare-recipe-book-lines <file1> <file2> [fileN...] | runtime compare-setup-payload-core <file1> <file2> [fileN...] | runtime compare-setup-launch-payload <file1> <file2> [fileN...] | runtime compare-post-special-conditions-scalars <file1> <file2> [fileN...] | runtime scan-candidate-table-headers <root-dir> | runtime scan-special-conditions <root-dir> | runtime scan-aligned-runtime-rule-band <root-dir> | runtime scan-post-special-conditions-scalars <root-dir> | runtime scan-post-special-conditions-tail <root-dir> | runtime scan-recipe-book-lines <root-dir> | runtime export-profile-block <save.gms> <profile.json>]"
|
"usage: rrt-cli [validate [repo-root] | finance eval <snapshot.json> | finance diff <left.json> <right.json> | runtime validate-fixture <fixture.json> | runtime summarize-fixture <fixture.json> | runtime export-fixture-state <fixture.json> <snapshot.json> | runtime diff-state <left.json> <right.json> | runtime summarize-state <snapshot.json> | runtime import-state <input.json> <snapshot.json> | runtime inspect-smp <file.smp> | runtime inspect-compact-event-dispatch-cluster <maps-dir> | runtime summarize-save-load <file.smp> | runtime load-save-slice <file.smp> | runtime inspect-save-company-chairman <file.smp> | runtime inspect-save-placed-structure-triplets <file.smp> | runtime compare-region-fixed-row-runs <left.gms> <right.gms> | runtime inspect-periodic-company-service-trace <file.smp> | runtime inspect-region-service-trace <file.smp> | runtime inspect-infrastructure-asset-trace <file.smp> | runtime inspect-save-region-queued-notice-records <file.smp> | runtime inspect-placed-structure-dynamic-side-buffer <file.smp> | runtime inspect-unclassified-save-collections <file.smp> | runtime import-save-state <file.smp> <snapshot.json> | runtime export-save-slice <file.smp> <save-slice.json> | runtime export-overlay-import <snapshot.json> <save-slice.json> <overlay-import.json> | runtime inspect-pk4 <file.pk4> | runtime inspect-cargo-types <CargoTypes-dir> | runtime inspect-cargo-skins <Cargo106.PK4> | runtime inspect-cargo-economy-sources <CargoTypes-dir> <Cargo106.PK4> | runtime inspect-cargo-production-selector <CargoTypes-dir> <Cargo106.PK4> | runtime inspect-cargo-price-selector <CargoTypes-dir> <Cargo106.PK4> | runtime inspect-win <file.win> | runtime extract-pk4-entry <file.pk4> <entry-name> <output-path> | runtime inspect-campaign-exe <RT3.exe> | runtime compare-classic-profile <save1.gms> <save2.gms> [saveN.gms...] | runtime compare-105-profile <save1.gms> <save2.gms> [saveN.gms...] | runtime compare-candidate-table <file1> <file2> [fileN...] | runtime compare-recipe-book-lines <file1> <file2> [fileN...] | runtime compare-setup-payload-core <file1> <file2> [fileN...] | runtime compare-setup-launch-payload <file1> <file2> [fileN...] | runtime compare-post-special-conditions-scalars <file1> <file2> [fileN...] | runtime scan-candidate-table-headers <root-dir> | runtime scan-special-conditions <root-dir> | runtime scan-aligned-runtime-rule-band <root-dir> | runtime scan-post-special-conditions-scalars <root-dir> | runtime scan-post-special-conditions-tail <root-dir> | runtime scan-recipe-book-lines <root-dir> | runtime export-profile-block <save.gms> <profile.json>]"
|
||||||
.into(),
|
.into(),
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
@ -1605,6 +1664,116 @@ fn run_runtime_inspect_smp(smp_path: &Path) -> Result<(), Box<dyn std::error::Er
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn run_runtime_inspect_compact_event_dispatch_cluster(
|
||||||
|
root_path: &Path,
|
||||||
|
) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
let mut input_paths = Vec::new();
|
||||||
|
collect_compact_event_dispatch_cluster_input_paths(root_path, &mut input_paths)?;
|
||||||
|
input_paths.sort();
|
||||||
|
|
||||||
|
let mut maps_with_event_runtime_collection = 0usize;
|
||||||
|
let mut maps_with_dispatch_strip_records = 0usize;
|
||||||
|
let mut dispatch_strip_record_count = 0usize;
|
||||||
|
let mut unknown_descriptor_occurrences =
|
||||||
|
BTreeMap::<u32, Vec<RuntimeCompactEventDispatchClusterOccurrence>>::new();
|
||||||
|
|
||||||
|
for path in &input_paths {
|
||||||
|
let inspection = inspect_smp_file(path)?;
|
||||||
|
let Some(summary) = inspection.event_runtime_collection_summary else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
maps_with_event_runtime_collection += 1;
|
||||||
|
|
||||||
|
let mut map_dispatch_strip_record_count = 0usize;
|
||||||
|
for record in &summary.records {
|
||||||
|
let matching_rows = record
|
||||||
|
.grouped_effect_rows
|
||||||
|
.iter()
|
||||||
|
.filter(|row| {
|
||||||
|
compact_event_dispatch_strip_opcode(row.opcode)
|
||||||
|
&& row.descriptor_label.is_none()
|
||||||
|
})
|
||||||
|
.fold(
|
||||||
|
BTreeMap::<u32, Vec<RuntimeCompactEventDispatchClusterRow>>::new(),
|
||||||
|
|mut grouped, row| {
|
||||||
|
grouped.entry(row.descriptor_id).or_default().push(
|
||||||
|
RuntimeCompactEventDispatchClusterRow {
|
||||||
|
group_index: row.group_index,
|
||||||
|
descriptor_id: row.descriptor_id,
|
||||||
|
descriptor_label: row.descriptor_label.clone(),
|
||||||
|
opcode: row.opcode,
|
||||||
|
raw_scalar_value: row.raw_scalar_value,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
grouped
|
||||||
|
},
|
||||||
|
);
|
||||||
|
if matching_rows.is_empty() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
map_dispatch_strip_record_count += 1;
|
||||||
|
let condition_tuples = record
|
||||||
|
.standalone_condition_rows
|
||||||
|
.iter()
|
||||||
|
.map(|row| RuntimeCompactEventDispatchClusterConditionTuple {
|
||||||
|
raw_condition_id: row.raw_condition_id,
|
||||||
|
subtype: row.subtype,
|
||||||
|
metric: row.metric.clone(),
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
let signature_family = compact_event_signature_family_from_notes(&record.notes);
|
||||||
|
|
||||||
|
for (descriptor_id, rows) in matching_rows {
|
||||||
|
unknown_descriptor_occurrences
|
||||||
|
.entry(descriptor_id)
|
||||||
|
.or_default()
|
||||||
|
.push(RuntimeCompactEventDispatchClusterOccurrence {
|
||||||
|
path: path.display().to_string(),
|
||||||
|
record_index: record.record_index,
|
||||||
|
live_entry_id: record.live_entry_id,
|
||||||
|
payload_family: record.payload_family.clone(),
|
||||||
|
signature_family: signature_family.clone(),
|
||||||
|
condition_tuples: condition_tuples.clone(),
|
||||||
|
rows,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if map_dispatch_strip_record_count > 0 {
|
||||||
|
maps_with_dispatch_strip_records += 1;
|
||||||
|
dispatch_strip_record_count += map_dispatch_strip_record_count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let unknown_descriptor_ids = unknown_descriptor_occurrences
|
||||||
|
.keys()
|
||||||
|
.copied()
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
let unknown_descriptor_special_condition_label_matches = unknown_descriptor_ids
|
||||||
|
.iter()
|
||||||
|
.filter_map(|descriptor_id| {
|
||||||
|
special_condition_label_for_compact_dispatch_descriptor(*descriptor_id)
|
||||||
|
.map(|label| format!("{descriptor_id} -> {label}"))
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
let report = RuntimeCompactEventDispatchClusterOutput {
|
||||||
|
root_path: root_path.display().to_string(),
|
||||||
|
report: RuntimeCompactEventDispatchClusterReport {
|
||||||
|
maps_scanned: input_paths.len(),
|
||||||
|
maps_with_event_runtime_collection,
|
||||||
|
maps_with_dispatch_strip_records,
|
||||||
|
dispatch_strip_record_count,
|
||||||
|
unknown_descriptor_ids,
|
||||||
|
unknown_descriptor_special_condition_label_matches,
|
||||||
|
unknown_descriptor_occurrences,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
println!("{}", serde_json::to_string_pretty(&report)?);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn run_runtime_summarize_save_load(smp_path: &Path) -> Result<(), Box<dyn std::error::Error>> {
|
fn run_runtime_summarize_save_load(smp_path: &Path) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let inspection = inspect_smp_file(smp_path)?;
|
let inspection = inspect_smp_file(smp_path)?;
|
||||||
let summary = inspection.save_load_summary.ok_or_else(|| {
|
let summary = inspection.save_load_summary.ok_or_else(|| {
|
||||||
|
|
@ -3731,6 +3900,73 @@ fn parse_special_condition_slot_index(label: &str) -> Option<u8> {
|
||||||
slot_index.parse().ok()
|
slot_index.parse().ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn compact_event_dispatch_strip_opcode(opcode: u8) -> bool {
|
||||||
|
matches!(opcode, 0x04..=0x08 | 0x0d | 0x10..=0x13 | 0x16)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn compact_event_signature_family_from_notes(notes: &[String]) -> Option<String> {
|
||||||
|
notes.iter().find_map(|note| {
|
||||||
|
note.strip_prefix("compact signature family = ")
|
||||||
|
.map(ToString::to_string)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn special_condition_label_for_compact_dispatch_descriptor(
|
||||||
|
descriptor_id: u32,
|
||||||
|
) -> Option<&'static str> {
|
||||||
|
let band_index = descriptor_id.checked_sub(535)? as usize;
|
||||||
|
SPECIAL_CONDITION_LABELS.get(band_index).copied()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn collect_compact_event_dispatch_cluster_input_paths(
|
||||||
|
root_path: &Path,
|
||||||
|
out: &mut Vec<PathBuf>,
|
||||||
|
) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
let metadata = match fs::symlink_metadata(root_path) {
|
||||||
|
Ok(metadata) => metadata,
|
||||||
|
Err(err) if err.kind() == std::io::ErrorKind::PermissionDenied => return Ok(()),
|
||||||
|
Err(err) => return Err(err.into()),
|
||||||
|
};
|
||||||
|
if metadata.file_type().is_symlink() {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
if root_path.is_file() {
|
||||||
|
if root_path
|
||||||
|
.extension()
|
||||||
|
.and_then(|ext| ext.to_str())
|
||||||
|
.is_some_and(|ext| ext.eq_ignore_ascii_case("gmp"))
|
||||||
|
{
|
||||||
|
out.push(root_path.to_path_buf());
|
||||||
|
}
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
let entries = match fs::read_dir(root_path) {
|
||||||
|
Ok(entries) => entries,
|
||||||
|
Err(err) if err.kind() == std::io::ErrorKind::PermissionDenied => return Ok(()),
|
||||||
|
Err(err) => return Err(err.into()),
|
||||||
|
};
|
||||||
|
|
||||||
|
for entry in entries {
|
||||||
|
let entry = entry?;
|
||||||
|
let path = entry.path();
|
||||||
|
if path.is_dir() {
|
||||||
|
collect_compact_event_dispatch_cluster_input_paths(&path, out)?;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if path
|
||||||
|
.extension()
|
||||||
|
.and_then(|ext| ext.to_str())
|
||||||
|
.is_some_and(|ext| ext.eq_ignore_ascii_case("gmp"))
|
||||||
|
{
|
||||||
|
out.push(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn parse_hex_offset(text: &str) -> Option<usize> {
|
fn parse_hex_offset(text: &str) -> Option<usize> {
|
||||||
text.strip_prefix("0x")
|
text.strip_prefix("0x")
|
||||||
.and_then(|digits| usize::from_str_radix(digits, 16).ok())
|
.and_then(|digits| usize::from_str_radix(digits, 16).ok())
|
||||||
|
|
|
||||||
|
|
@ -9485,6 +9485,16 @@ fn parse_event_runtime_collection_summary_with_tag_width(
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
mutation_candidate_unknown_descriptor_ids.sort_unstable();
|
mutation_candidate_unknown_descriptor_ids.sort_unstable();
|
||||||
mutation_candidate_unknown_descriptor_ids.dedup();
|
mutation_candidate_unknown_descriptor_ids.dedup();
|
||||||
|
let mut mutation_candidate_special_condition_label_matches =
|
||||||
|
mutation_candidate_unknown_descriptor_ids
|
||||||
|
.iter()
|
||||||
|
.filter_map(|descriptor_id| {
|
||||||
|
known_special_condition_label_for_compact_descriptor_id(*descriptor_id)
|
||||||
|
.map(|label| format!("{descriptor_id} -> {label}"))
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
mutation_candidate_special_condition_label_matches.sort();
|
||||||
|
mutation_candidate_special_condition_label_matches.dedup();
|
||||||
let mut dispatch_strip_unknown_condition_ids = records
|
let mut dispatch_strip_unknown_condition_ids = records
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|record| {
|
.filter(|record| {
|
||||||
|
|
@ -9533,6 +9543,12 @@ fn parse_event_runtime_collection_summary_with_tag_width(
|
||||||
mutation_candidate_unknown_descriptor_ids
|
mutation_candidate_unknown_descriptor_ids
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
if !mutation_candidate_special_condition_label_matches.is_empty() {
|
||||||
|
control_lane_notes.push(format!(
|
||||||
|
"unlabeled 0x00431b20 dispatch-strip descriptor ids matching known special-condition label_id-2000 values = {:?}",
|
||||||
|
mutation_candidate_special_condition_label_matches
|
||||||
|
));
|
||||||
|
}
|
||||||
if !dispatch_strip_unknown_condition_ids.is_empty() {
|
if !dispatch_strip_unknown_condition_ids.is_empty() {
|
||||||
control_lane_notes.push(format!(
|
control_lane_notes.push(format!(
|
||||||
"standalone condition ids still missing checked-in labels in the 0x00431b20 dispatch strip = {:?}",
|
"standalone condition ids still missing checked-in labels in the 0x00431b20 dispatch strip = {:?}",
|
||||||
|
|
@ -9587,6 +9603,16 @@ fn opcode_reaches_world_apply_compact_runtime_effect_dispatch_strip(opcode: u8)
|
||||||
matches!(opcode, 0x04..=0x08 | 0x0d | 0x10..=0x13 | 0x16)
|
matches!(opcode, 0x04..=0x08 | 0x0d | 0x10..=0x13 | 0x16)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn known_special_condition_label_for_compact_descriptor_id(
|
||||||
|
descriptor_id: u32,
|
||||||
|
) -> Option<&'static str> {
|
||||||
|
let label_id = descriptor_id.checked_add(2000)?;
|
||||||
|
KNOWN_SPECIAL_CONDITION_DEFINITIONS
|
||||||
|
.iter()
|
||||||
|
.find(|definition| definition.label_id == label_id)
|
||||||
|
.map(|definition| definition.label)
|
||||||
|
}
|
||||||
|
|
||||||
fn try_parse_nondirect_event_runtime_record_summaries(
|
fn try_parse_nondirect_event_runtime_record_summaries(
|
||||||
records_payload: &[u8],
|
records_payload: &[u8],
|
||||||
records_payload_offset: usize,
|
records_payload_offset: usize,
|
||||||
|
|
@ -23874,8 +23900,8 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn checked_in_event_effect_table_covers_the_full_exported_descriptor_set() {
|
fn checked_in_event_effect_table_covers_the_full_exported_descriptor_set() {
|
||||||
let rows = checked_in_event_effect_descriptor_rows();
|
let rows = checked_in_event_effect_descriptor_rows();
|
||||||
assert_eq!(rows.len(), 520);
|
assert_eq!(rows.len(), 614);
|
||||||
for descriptor_id in 0..520_u32 {
|
for descriptor_id in 0..614_u32 {
|
||||||
assert!(
|
assert!(
|
||||||
real_grouped_effect_descriptor_metadata(descriptor_id).is_some(),
|
real_grouped_effect_descriptor_metadata(descriptor_id).is_some(),
|
||||||
"descriptor {descriptor_id} should be recoverable from the checked-in effect table"
|
"descriptor {descriptor_id} should be recoverable from the checked-in effect table"
|
||||||
|
|
|
||||||
|
|
@ -281,13 +281,26 @@ Working rule:
|
||||||
`East Coast, USA.gmp`, `Japan Trembles.gmp`, and `State of Germany.gmp`; it does not appear on
|
`East Coast, USA.gmp`, `Japan Trembles.gmp`, and `State of Germany.gmp`; it does not appear on
|
||||||
the `opcode 8` deactivation branch, so grouped descriptor id `548` is not just the obvious
|
the `opcode 8` deactivation branch, so grouped descriptor id `548` is not just the obvious
|
||||||
compact stand-in for ordinary descriptor `13`
|
compact stand-in for ordinary descriptor `13`
|
||||||
- the frontier is now best treated as a small compact-only opcode-`8` cluster rather than a
|
- that compact opcode-`8` cluster is now grounded as an artifact-boundary problem rather than a
|
||||||
one-id anomaly:
|
mysterious compact-only id family:
|
||||||
the installed-map sweep now shows unlabeled grouped descriptor ids `[521, 526, 528, 548, 563]`
|
direct binary inspection of the `0x00610398` EventEffects table shows the contiguous table does
|
||||||
in the `0x00431b20` dispatch strip, all currently on opcode `8`, with current sightings in
|
not stop at row `519`; it continues cleanly through row `613`, with the extractor-side
|
||||||
`Alternate USA.gmp`, `Rhodes Unfinished.gmp`, `Louisiana.gmp`, and `Texas Tea.gmp`; the next
|
sequential descriptor invariant still holding. The checked-in extractor and semantic catalog now
|
||||||
static-analysis pass should treat that as one branch family above `0x00426d60`, not five
|
cover the full `614`-row export instead of the old truncated `520`-row slice
|
||||||
unrelated missing labels
|
- that closes the earlier unlabeled cluster:
|
||||||
|
grouped descriptor ids `521`, `526`, `528`, `548`, and `563` are now recovered as
|
||||||
|
`Add Building Slot 19`, `Add Building Slot 24`, `Add Building Slot 26`, `Add Building Slot 46`,
|
||||||
|
and `Add Building Slot 61` respectively, all in the widened shell-owned add-building strip
|
||||||
|
`503..613`
|
||||||
|
- the earlier `label_id - 2000` bridge for `548` and `563` is now known to be a false lead:
|
||||||
|
those numeric collisions hit the special-condition label table
|
||||||
|
(`Disable Building Stations`, `Completely Disable Money-Related Things`), but the extended
|
||||||
|
EventEffects table proves the actual grouped descriptors are add-building slots, not
|
||||||
|
special-condition verbs
|
||||||
|
- the compact opcode-`8` frontier therefore shifts:
|
||||||
|
the next static-analysis pass should target which add-building slot numbers correspond to which
|
||||||
|
concrete building classes and whether opcode `8` on that shell-owned strip means a distinct
|
||||||
|
add-building shell flow, not more missing-label recovery
|
||||||
- the concrete owner strip above that bundle is grounded now too:
|
- the concrete owner strip above that bundle is grounded now too:
|
||||||
`0x00433060` is the direct non-direct serializer loop that writes `0x4e99/0x4e9a/0x4e9b`,
|
`0x00433060` is the direct non-direct serializer loop that writes `0x4e99/0x4e9a/0x4e9b`,
|
||||||
calls `0x00430d70` per live collection row, and sits beside the sibling `0x00433130` size/load
|
calls `0x00430d70` per live collection row, and sits beside the sibling `0x00433130` size/load
|
||||||
|
|
|
||||||
|
|
@ -147,6 +147,10 @@ def classify(
|
||||||
parameter_family = "company_governance_scalar"
|
parameter_family = "company_governance_scalar"
|
||||||
runtime_status = "executable"
|
runtime_status = "executable"
|
||||||
executable_in_runtime = True
|
executable_in_runtime = True
|
||||||
|
elif 39 <= descriptor_id <= 54:
|
||||||
|
parameter_family = "runtime_variable_scalar"
|
||||||
|
runtime_status = "executable"
|
||||||
|
executable_in_runtime = True
|
||||||
elif 59 <= descriptor_id <= 104:
|
elif 59 <= descriptor_id <= 104:
|
||||||
parameter_family = "world_scalar_override"
|
parameter_family = "world_scalar_override"
|
||||||
runtime_key = normalize_world_scalar_key(label)
|
runtime_key = normalize_world_scalar_key(label)
|
||||||
|
|
@ -217,14 +221,10 @@ def classify(
|
||||||
runtime_key = "world.all_electric_locos_available"
|
runtime_key = "world.all_electric_locos_available"
|
||||||
runtime_status = "executable"
|
runtime_status = "executable"
|
||||||
executable_in_runtime = True
|
executable_in_runtime = True
|
||||||
elif 503 <= descriptor_id <= 519:
|
elif 503 <= descriptor_id <= 613:
|
||||||
parameter_family = "world_building_spawn"
|
parameter_family = "world_building_spawn"
|
||||||
label = f"Add Building Slot {descriptor_id - 502}"
|
label = f"Add Building Slot {descriptor_id - 502}"
|
||||||
runtime_status = "shell_owned"
|
runtime_status = "shell_owned"
|
||||||
elif signature_byte_0x63 == 0 and signature_byte_0x64 == 0x8F:
|
|
||||||
parameter_family = "runtime_variable_scalar"
|
|
||||||
runtime_status = "executable"
|
|
||||||
executable_in_runtime = True
|
|
||||||
elif "Earthquake" in label or "Storm" in label:
|
elif "Earthquake" in label or "Storm" in label:
|
||||||
parameter_family = "world_disaster_scalar"
|
parameter_family = "world_disaster_scalar"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ from pathlib import Path
|
||||||
|
|
||||||
TABLE_BASE_VA = 0x00610398
|
TABLE_BASE_VA = 0x00610398
|
||||||
ROW_STRIDE = 0x6E
|
ROW_STRIDE = 0x6E
|
||||||
ROW_COUNT = 520
|
MAX_ROW_COUNT = 2048
|
||||||
IMAGE_BASE = 0x00400000
|
IMAGE_BASE = 0x00400000
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -27,17 +27,20 @@ def load_lng_labels(path: Path) -> dict[int, str]:
|
||||||
def extract_rows(exe_bytes: bytes, labels: dict[int, str]) -> list[dict[str, object]]:
|
def extract_rows(exe_bytes: bytes, labels: dict[int, str]) -> list[dict[str, object]]:
|
||||||
table_offset = TABLE_BASE_VA - IMAGE_BASE
|
table_offset = TABLE_BASE_VA - IMAGE_BASE
|
||||||
rows: list[dict[str, object]] = []
|
rows: list[dict[str, object]] = []
|
||||||
for row_index in range(ROW_COUNT):
|
for row_index in range(MAX_ROW_COUNT):
|
||||||
row = exe_bytes[
|
row = exe_bytes[
|
||||||
table_offset + row_index * ROW_STRIDE : table_offset + (row_index + 1) * ROW_STRIDE
|
table_offset + row_index * ROW_STRIDE : table_offset + (row_index + 1) * ROW_STRIDE
|
||||||
]
|
]
|
||||||
if len(row) < ROW_STRIDE:
|
if len(row) < ROW_STRIDE:
|
||||||
break
|
break
|
||||||
|
descriptor_id = struct.unpack_from("<I", row, 0x04)[0]
|
||||||
|
if descriptor_id != row_index:
|
||||||
|
break
|
||||||
label_id = struct.unpack_from("<H", row, 0x6A)[0]
|
label_id = struct.unpack_from("<H", row, 0x6A)[0]
|
||||||
rows.append(
|
rows.append(
|
||||||
{
|
{
|
||||||
"row_index": row_index,
|
"row_index": row_index,
|
||||||
"descriptor_id": struct.unpack_from("<I", row, 0x04)[0],
|
"descriptor_id": descriptor_id,
|
||||||
"selector_order": struct.unpack_from("<f", row, 0x00)[0],
|
"selector_order": struct.unpack_from("<f", row, 0x00)[0],
|
||||||
"target_mask_bits": row[0x65],
|
"target_mask_bits": row[0x65],
|
||||||
"label_id": label_id,
|
"label_id": label_id,
|
||||||
|
|
@ -62,12 +65,12 @@ def main() -> None:
|
||||||
artifact = {
|
artifact = {
|
||||||
"table_base_va": f"0x{TABLE_BASE_VA:08x}",
|
"table_base_va": f"0x{TABLE_BASE_VA:08x}",
|
||||||
"row_stride_hex": f"0x{ROW_STRIDE:02x}",
|
"row_stride_hex": f"0x{ROW_STRIDE:02x}",
|
||||||
"descriptor_count": ROW_COUNT,
|
|
||||||
"binary_path_hint": str(args.exe),
|
"binary_path_hint": str(args.exe),
|
||||||
"language_path_hint": str(args.lng),
|
"language_path_hint": str(args.lng),
|
||||||
"binary_sha256": hashlib.sha256(exe_bytes).hexdigest(),
|
"binary_sha256": hashlib.sha256(exe_bytes).hexdigest(),
|
||||||
"descriptors": extract_rows(exe_bytes, labels),
|
|
||||||
}
|
}
|
||||||
|
artifact["descriptors"] = extract_rows(exe_bytes, labels)
|
||||||
|
artifact["descriptor_count"] = len(artifact["descriptors"])
|
||||||
args.out.write_text(json.dumps(artifact, indent=2) + "\n", encoding="utf-8")
|
args.out.write_text(json.dumps(artifact, indent=2) + "\n", encoding="utf-8")
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue