Rehost offline building type source catalog
This commit is contained in:
parent
9c8a5005f4
commit
c21a47d60f
6 changed files with 4541 additions and 12 deletions
4336
artifacts/exports/rt3-1.06/building-type-sources.json
Normal file
4336
artifacts/exports/rt3-1.06/building-type-sources.json
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -17,17 +17,18 @@ use rrt_model::{
|
|||
load_binary_summary, load_function_map,
|
||||
};
|
||||
use rrt_runtime::{
|
||||
CAMPAIGN_SCENARIO_COUNT, CampaignExeInspectionReport, CargoEconomySourceReport,
|
||||
CargoSelectorReport, CargoSkinInspectionReport, CargoTypeInspectionReport,
|
||||
OBSERVED_CAMPAIGN_SCENARIO_NAMES, OVERLAY_IMPORT_DOCUMENT_FORMAT_VERSION, Pk4ExtractionReport,
|
||||
Pk4InspectionReport, RuntimeOverlayImportDocument, RuntimeOverlayImportDocumentSource,
|
||||
RuntimeSaveSliceDocument, RuntimeSaveSliceDocumentSource, RuntimeSnapshotDocument,
|
||||
RuntimeSnapshotSource, RuntimeSummary, SAVE_SLICE_DOCUMENT_FORMAT_VERSION,
|
||||
SNAPSHOT_FORMAT_VERSION, SmpClassicPackedProfileBlock, SmpInspectionReport, SmpLoadedSaveSlice,
|
||||
SmpRt3105PackedProfileBlock, SmpSaveLoadSummary, WinInspectionReport,
|
||||
compare_save_region_fixed_row_run_candidates, execute_step_command, extract_pk4_entry_file,
|
||||
inspect_campaign_exe_file, inspect_cargo_economy_sources_with_bindings, inspect_cargo_skin_pk4,
|
||||
inspect_cargo_types_dir, inspect_pk4_file, inspect_save_company_and_chairman_analysis_file,
|
||||
BuildingTypeSourceReport, CAMPAIGN_SCENARIO_COUNT, CampaignExeInspectionReport,
|
||||
CargoEconomySourceReport, CargoSelectorReport, CargoSkinInspectionReport,
|
||||
CargoTypeInspectionReport, OBSERVED_CAMPAIGN_SCENARIO_NAMES,
|
||||
OVERLAY_IMPORT_DOCUMENT_FORMAT_VERSION, Pk4ExtractionReport, Pk4InspectionReport,
|
||||
RuntimeOverlayImportDocument, RuntimeOverlayImportDocumentSource, RuntimeSaveSliceDocument,
|
||||
RuntimeSaveSliceDocumentSource, RuntimeSnapshotDocument, RuntimeSnapshotSource, RuntimeSummary,
|
||||
SAVE_SLICE_DOCUMENT_FORMAT_VERSION, SNAPSHOT_FORMAT_VERSION, SmpClassicPackedProfileBlock,
|
||||
SmpInspectionReport, SmpLoadedSaveSlice, SmpRt3105PackedProfileBlock, SmpSaveLoadSummary,
|
||||
WinInspectionReport, compare_save_region_fixed_row_run_candidates, execute_step_command,
|
||||
extract_pk4_entry_file, inspect_building_types_dir, inspect_campaign_exe_file,
|
||||
inspect_cargo_economy_sources_with_bindings, inspect_cargo_skin_pk4, inspect_cargo_types_dir,
|
||||
inspect_pk4_file, inspect_save_company_and_chairman_analysis_file,
|
||||
inspect_save_infrastructure_asset_trace_file, inspect_save_periodic_company_service_trace_file,
|
||||
inspect_save_placed_structure_dynamic_side_buffer_file,
|
||||
inspect_save_region_queued_notice_records_file, inspect_save_region_service_trace_file,
|
||||
|
|
@ -187,6 +188,9 @@ enum Command {
|
|||
RuntimeInspectCargoTypes {
|
||||
cargo_types_dir: PathBuf,
|
||||
},
|
||||
RuntimeInspectBuildingTypeSources {
|
||||
building_types_dir: PathBuf,
|
||||
},
|
||||
RuntimeInspectCargoSkins {
|
||||
cargo_skin_pk4_path: PathBuf,
|
||||
},
|
||||
|
|
@ -446,6 +450,12 @@ struct RuntimeCargoTypeInspectionOutput {
|
|||
inspection: CargoTypeInspectionReport,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
struct RuntimeBuildingTypeInspectionOutput {
|
||||
path: String,
|
||||
inspection: BuildingTypeSourceReport,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
struct RuntimeCargoSkinInspectionOutput {
|
||||
path: String,
|
||||
|
|
@ -1079,6 +1089,9 @@ fn real_main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
Command::RuntimeInspectCargoTypes { cargo_types_dir } => {
|
||||
run_runtime_inspect_cargo_types(&cargo_types_dir)?;
|
||||
}
|
||||
Command::RuntimeInspectBuildingTypeSources { building_types_dir } => {
|
||||
run_runtime_inspect_building_type_sources(&building_types_dir)?;
|
||||
}
|
||||
Command::RuntimeInspectCargoSkins {
|
||||
cargo_skin_pk4_path,
|
||||
} => {
|
||||
|
|
@ -1377,6 +1390,13 @@ fn parse_command() -> Result<Command, Box<dyn std::error::Error>> {
|
|||
cargo_types_dir: PathBuf::from(path),
|
||||
})
|
||||
}
|
||||
[command, subcommand, path]
|
||||
if command == "runtime" && subcommand == "inspect-building-type-sources" =>
|
||||
{
|
||||
Ok(Command::RuntimeInspectBuildingTypeSources {
|
||||
building_types_dir: PathBuf::from(path),
|
||||
})
|
||||
}
|
||||
[command, subcommand, path]
|
||||
if command == "runtime" && subcommand == "inspect-cargo-skins" =>
|
||||
{
|
||||
|
|
@ -1543,7 +1563,7 @@ fn parse_command() -> Result<Command, Box<dyn std::error::Error>> {
|
|||
})
|
||||
}
|
||||
_ => 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 inspect-candidate-table <file.smp> | runtime inspect-compact-event-dispatch-cluster <maps-dir> | runtime inspect-compact-event-dispatch-cluster-counts <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>]"
|
||||
"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-candidate-table <file.smp> | runtime inspect-compact-event-dispatch-cluster <maps-dir> | runtime inspect-compact-event-dispatch-cluster-counts <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-building-type-sources <BuildingTypes-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(),
|
||||
),
|
||||
}
|
||||
|
|
@ -2203,6 +2223,17 @@ fn run_runtime_inspect_cargo_types(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn run_runtime_inspect_building_type_sources(
|
||||
building_types_dir: &Path,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let report = RuntimeBuildingTypeInspectionOutput {
|
||||
path: building_types_dir.display().to_string(),
|
||||
inspection: inspect_building_types_dir(building_types_dir)?,
|
||||
};
|
||||
println!("{}", serde_json::to_string_pretty(&report)?);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn run_runtime_inspect_cargo_skins(
|
||||
cargo_skin_pk4_path: &Path,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ pub const REQUIRED_EXPORTS: &[&str] = &[
|
|||
"artifacts/exports/rt3-1.06/event-effects-cargo-bindings.json",
|
||||
"artifacts/exports/rt3-1.06/event-effects-building-bindings.json",
|
||||
"artifacts/exports/rt3-1.06/event-effects-semantic-catalog.json",
|
||||
"artifacts/exports/rt3-1.06/building-type-sources.json",
|
||||
"artifacts/exports/rt3-1.06/economy-cargo-sources.json",
|
||||
"artifacts/exports/rt3-1.06/selected-year-bucket-ladder.json",
|
||||
];
|
||||
|
|
|
|||
148
crates/rrt-runtime/src/building.rs
Normal file
148
crates/rrt-runtime/src/building.rs
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
use std::collections::{BTreeMap, BTreeSet};
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum BuildingTypeSourceKind {
|
||||
Bca,
|
||||
Bty,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct BuildingTypeSourceFile {
|
||||
pub file_name: String,
|
||||
pub raw_stem: String,
|
||||
pub canonical_stem: String,
|
||||
pub source_kind: BuildingTypeSourceKind,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct BuildingTypeSourceEntry {
|
||||
pub canonical_stem: String,
|
||||
pub raw_stems: Vec<String>,
|
||||
pub source_kinds: Vec<BuildingTypeSourceKind>,
|
||||
pub file_names: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct BuildingTypeSourceReport {
|
||||
pub directory_path: String,
|
||||
pub bca_file_count: usize,
|
||||
pub bty_file_count: usize,
|
||||
pub unique_canonical_stem_count: usize,
|
||||
pub notes: Vec<String>,
|
||||
pub files: Vec<BuildingTypeSourceFile>,
|
||||
pub entries: Vec<BuildingTypeSourceEntry>,
|
||||
}
|
||||
|
||||
pub fn inspect_building_types_dir(
|
||||
path: &Path,
|
||||
) -> Result<BuildingTypeSourceReport, Box<dyn std::error::Error>> {
|
||||
let mut files = Vec::new();
|
||||
for entry in fs::read_dir(path)? {
|
||||
let entry = entry?;
|
||||
if !entry.file_type()?.is_file() {
|
||||
continue;
|
||||
}
|
||||
let file_name = entry.file_name().to_string_lossy().into_owned();
|
||||
let Some(extension) = Path::new(&file_name)
|
||||
.extension()
|
||||
.and_then(|extension| extension.to_str())
|
||||
.map(|extension| extension.to_ascii_lowercase())
|
||||
else {
|
||||
continue;
|
||||
};
|
||||
let source_kind = match extension.as_str() {
|
||||
"bca" => BuildingTypeSourceKind::Bca,
|
||||
"bty" => BuildingTypeSourceKind::Bty,
|
||||
_ => continue,
|
||||
};
|
||||
let raw_stem = Path::new(&file_name)
|
||||
.file_stem()
|
||||
.and_then(|stem| stem.to_str())
|
||||
.unwrap_or("")
|
||||
.to_string();
|
||||
if raw_stem.is_empty() {
|
||||
continue;
|
||||
}
|
||||
files.push(BuildingTypeSourceFile {
|
||||
file_name,
|
||||
canonical_stem: canonicalize_building_stem(&raw_stem),
|
||||
raw_stem,
|
||||
source_kind,
|
||||
});
|
||||
}
|
||||
|
||||
files.sort_by(|left, right| {
|
||||
left.canonical_stem
|
||||
.cmp(&right.canonical_stem)
|
||||
.then_with(|| left.file_name.cmp(&right.file_name))
|
||||
});
|
||||
|
||||
let mut grouped = BTreeMap::<String, Vec<&BuildingTypeSourceFile>>::new();
|
||||
for file in &files {
|
||||
grouped
|
||||
.entry(file.canonical_stem.clone())
|
||||
.or_default()
|
||||
.push(file);
|
||||
}
|
||||
|
||||
let entries = grouped
|
||||
.into_iter()
|
||||
.map(|(canonical_stem, group)| BuildingTypeSourceEntry {
|
||||
canonical_stem,
|
||||
raw_stems: group
|
||||
.iter()
|
||||
.map(|file| file.raw_stem.clone())
|
||||
.collect::<BTreeSet<_>>()
|
||||
.into_iter()
|
||||
.collect(),
|
||||
source_kinds: group
|
||||
.iter()
|
||||
.map(|file| file.source_kind.clone())
|
||||
.collect::<BTreeSet<_>>()
|
||||
.into_iter()
|
||||
.collect(),
|
||||
file_names: group
|
||||
.iter()
|
||||
.map(|file| file.file_name.clone())
|
||||
.collect::<BTreeSet<_>>()
|
||||
.into_iter()
|
||||
.collect(),
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let bca_file_count = files
|
||||
.iter()
|
||||
.filter(|file| matches!(file.source_kind, BuildingTypeSourceKind::Bca))
|
||||
.count();
|
||||
let bty_file_count = files
|
||||
.iter()
|
||||
.filter(|file| matches!(file.source_kind, BuildingTypeSourceKind::Bty))
|
||||
.count();
|
||||
|
||||
let notes = vec![
|
||||
"BuildingTypes sources are grouped by a canonical stem that lowercases and strips spaces, underscores, and hyphens so paired .bca/.bty variants collapse onto one asset token.".to_string(),
|
||||
"This report is an offline asset-pool view only; it does not by itself assign live candidate ids or prove scenario candidate-table availability.".to_string(),
|
||||
];
|
||||
|
||||
Ok(BuildingTypeSourceReport {
|
||||
directory_path: path.display().to_string(),
|
||||
bca_file_count,
|
||||
bty_file_count,
|
||||
unique_canonical_stem_count: entries.len(),
|
||||
notes,
|
||||
files,
|
||||
entries,
|
||||
})
|
||||
}
|
||||
|
||||
fn canonicalize_building_stem(stem: &str) -> String {
|
||||
stem.chars()
|
||||
.filter(|ch| !matches!(ch, ' ' | '_' | '-'))
|
||||
.flat_map(|ch| ch.to_lowercase())
|
||||
.collect()
|
||||
}
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
pub mod building;
|
||||
pub mod calendar;
|
||||
pub mod campaign_exe;
|
||||
pub mod economy;
|
||||
|
|
@ -10,6 +11,10 @@ pub mod step;
|
|||
pub mod summary;
|
||||
pub mod win;
|
||||
|
||||
pub use building::{
|
||||
BuildingTypeSourceEntry, BuildingTypeSourceFile, BuildingTypeSourceKind,
|
||||
BuildingTypeSourceReport, inspect_building_types_dir,
|
||||
};
|
||||
pub use calendar::{CalendarPoint, MONTH_SLOTS_PER_YEAR, PHASE_SLOTS_PER_MONTH, TICKS_PER_PHASE};
|
||||
pub use campaign_exe::{
|
||||
CAMPAIGN_SCENARIO_COUNT, CampaignExeInspectionReport, CampaignPageBand, CampaignScenarioEntry,
|
||||
|
|
|
|||
|
|
@ -354,6 +354,14 @@ Working rule:
|
|||
shell-owned placement-flow ownership on that strip, not more missing-label recovery: the
|
||||
descriptor-side candidate bridge is now checked in across `503..613`, and the honest remaining
|
||||
boundary is the missing non-hook name catalog for candidate ids `67..110`
|
||||
- the new offline `BuildingTypes` source report sharpens that missing name-catalog boundary too:
|
||||
`runtime inspect-building-type-sources rt3_wineprefix/drive_c/rt3/Data/BuildingTypes`
|
||||
now reports `77` `.bca` files, `200` `.bty` files, and `208` canonical asset stems, but only
|
||||
`43` of those canonical stems overlap the live named candidate run `0..66`. The numbered live
|
||||
`Port00..11` and `Warehouse00..11` names collapse to generic asset stems `Port` and
|
||||
`Warehouse`, while `165` canonical stems exist only in the broader asset pool. So the
|
||||
`BuildingTypes` directory is now grounded as a wider offline source catalog, but not yet as a
|
||||
direct second live candidate-name owner for descriptor-side ids `67..110`
|
||||
- the concrete owner strip above that bundle is grounded now too:
|
||||
`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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue