diff --git a/src/techblox/block_group_entity.rs b/src/techblox/block_group_entity.rs index e55c093..c8015a3 100644 --- a/src/techblox/block_group_entity.rs +++ b/src/techblox/block_group_entity.rs @@ -21,6 +21,10 @@ impl SerializedEntityDescriptor for BlockGroupEntity { vec![&self.saved_block_group_id, &self.block_group_transform] } + + fn hash_name(&self) -> u32 { + Self::hash("BlockGroupEntityDescriptorV0") + } } /// Saved block group identifier entity component. diff --git a/src/techblox/blocks/block_entity.rs b/src/techblox/blocks/block_entity.rs index c2b4fb6..1cd6524 100644 --- a/src/techblox/blocks/block_entity.rs +++ b/src/techblox/blocks/block_entity.rs @@ -55,4 +55,8 @@ impl SerializedEntityDescriptor for BlockEntity { &self.colour_component, &self.group_component] } + + fn hash_name(&self) -> u32 { + Self::hash("StandardBlockEntityDescriptorV4") // 1357220432 + } } diff --git a/src/techblox/blocks/wire_entity.rs b/src/techblox/blocks/wire_entity.rs index e761c3f..6f39dce 100644 --- a/src/techblox/blocks/wire_entity.rs +++ b/src/techblox/blocks/wire_entity.rs @@ -17,6 +17,10 @@ impl SerializedEntityDescriptor for SerializedWireEntity { fn components<'a>(&'a self) -> Vec<&'a dyn SerializedEntityComponent> { vec![&self.save_data_component] } + + fn hash_name(&self) -> u32 { + Self::hash("WireEntityDescriptorMock") // 1818308818 + } } /// Wire connection information that is saved. @@ -49,6 +53,10 @@ impl SerializedEntityDescriptor for SerializedGlobalWireSettingsEntity { fn components<'a>(&'a self) -> Vec<&'a dyn SerializedEntityComponent> { vec![&self.settings_component] } + + fn hash_name(&self) -> u32 { + Self::hash("GlobalWireSettingsEntityDescriptor") // 1820064641 + } } /// Wire settings applied to the whole game save diff --git a/src/techblox/camera.rs b/src/techblox/camera.rs index bc6052d..3e51643 100644 --- a/src/techblox/camera.rs +++ b/src/techblox/camera.rs @@ -17,6 +17,10 @@ impl SerializedEntityDescriptor for SerializedFlyCamEntity { fn components<'a>(&'a self) -> Vec<&'a dyn SerializedEntityComponent> { vec![&self.rb_component] } + + fn hash_name(&self) -> u32 { + Self::hash("FlyCamEntityDescriptorV0") // 252528354 + } } /// Physical object info for simulation @@ -43,6 +47,10 @@ impl SerializedEntityDescriptor for SerializedPhysicsCameraEntity { fn components<'a>(&'a self) -> Vec<&'a dyn SerializedEntityComponent> { vec![&self.cam_component] } + + fn hash_name(&self) -> u32 { + Self::hash("CharacterCameraEntityDescriptorV1") // 3850144645 + } } /// Physics camera component diff --git a/src/techblox/entity_traits.rs b/src/techblox/entity_traits.rs index 56c05b5..e332143 100644 --- a/src/techblox/entity_traits.rs +++ b/src/techblox/entity_traits.rs @@ -14,6 +14,12 @@ pub trait SerializedEntityDescriptor: Parsable { fn serialized_components() -> u8 where Self: Sized; /// Components that this entity is comprised of fn components<'a>(&'a self) -> Vec<&'a dyn SerializedEntityComponent>; + /// Hash of descriptor name + fn hash_name(&self) -> u32; + /// Hash of descriptor name + fn hash(s: &str) -> u32 where Self: Sized { + crate::techblox::hashname(s) + } } /// Serializable entity component. diff --git a/tests/techblox_parsing.rs b/tests/techblox_parsing.rs index 9453363..7546e34 100644 --- a/tests/techblox_parsing.rs +++ b/tests/techblox_parsing.rs @@ -14,7 +14,65 @@ const GAMESAVE_PATH2: &str = "tests/GameSave2.Techblox"; #[cfg(feature = "techblox")] const HASHNAMES: &[&str] = &[ + "BlockGroupEntityDescriptorV0", + "StandardBlockEntityDescriptorV4", + "BatteryEntityDescriptorV4", + "MotorEntityDescriptorV7", + "LeverEntityDescriptorV7", + "ButtonEntityDescriptorV6", + "JointBlockEntityDescriptorV3", + "ServoEntityDescriptorV7", + "PistonEntityDescriptorV6", + "DampedSpringEntityDescriptorV5", + "DampedAngularSpringEntityDescriptorV4", + "SpawnPointEntityDescriptorV6", + "BuildingSpawnPointEntityDescriptorV4", + "TriggerEntityDescriptorV6", + "PilotSeatEntityDescriptorV4", + "PilotSeatEntityDescriptorV3", + "TextBlockEntityDescriptorV4", + "PassengerSeatEntityDescriptorV4", + "PassengerSeatEntityDescriptorV3", + "LogicBlockEntityDescriptorV1", + "TyreEntityDescriptorV1", + "ObjectIDEntityDescriptorV1", + "MoverEntityDescriptorV1", + "RotatorEntityDescriptorV1", + "DamperEntityDescriptorV1", + "AdvancedDamperEntityDescriptorV1", + "CoMEntityDescriptor", + "FilterBlockEntityDescriptorV1", + "ConstrainerEntityDescriptorV1", + "NumberToTextBlockEntityDescriptorV1", + "CentreHudBlockEntityDescriptorV1", + "ObjectiveHudBlockEntityDescriptorV1", + "GameStatsHudBlockEntityDescriptorV1", + "GameOverHudBlockEntityDescriptorV1", + "TimerBlockEntityDescriptorV1", + "BitBlockEntityDescriptorV2", + "ConstantBlockEntityDescriptor", + "CounterBlockEntityDescriptorV1", + "SimpleSfxEntityDescriptorV1", + "LoopedSfxEntityDescriptorV1", + "MusicBlockEntityDescriptorV1", + "ProjectileBlockEntityDescriptorV1", + "DamagingSurfaceEntityDescriptorV1", + "DestructionManagerEntityDescriptorV1", + "ChunkDestructionBlockEntityDescriptorV1", + "ClusterDestructionBlockEntityDescriptorV1", + "PickupBlockEntityDescriptorV1", + "PointLightEntityDescriptorV1", + "SpotLightEntityDescriptorV1", + "SunLightEntityDescriptorV1", + "AmbientLightEntityDescriptorV1", + "FogEntityDescriptorV1", + "SkyEntityDescriptorV1", + "SynchronizedWireBlockEntityDescriptor", + "WheelRigEntityDescriptor", + "WheelRigSteerableEntityDescriptor", + "EngineBlockEntityDescriptor", + "WireEntityDescriptorMock", "GlobalWireSettingsEntityDescriptor", "FlyCamEntityDescriptorV0", @@ -35,6 +93,7 @@ fn techblox_gamesave_parse() -> Result<(), ()> { } for i in 0..(gs.group_len as usize) { assert_eq!(gs.group_headers[i].component_count, techblox::BlockGroupEntity::serialized_components()); + assert_eq!(gs.group_headers[i].hash, gs.cube_groups[i].hash_name()); } for i in 1..(gs.cube_len as usize) { //assert_eq!(gs.cube_headers[i-1].hash, gs.cube_headers[i].hash); @@ -46,16 +105,21 @@ fn techblox_gamesave_parse() -> Result<(), ()> { for i in 0..(gs.cube_len as usize) { assert!(gs.cube_headers[i].component_count >= blocks::BlockEntity::serialized_components()); //println!("#{} components: {}", i, gs.cube_headers[i].component_count); + assert_eq!(gs.cube_headers[i].hash, gs.cube_entities[i].hash_name()); } //println!("Parsed wire settings hash: {} obsolete? {}", gs.wire_settings_header.hash, gs.wire_settings_entity.settings_component.obsolete != 0); assert_eq!(gs.wire_settings_header.hash, EntityHeader::from_name("GlobalWireSettingsEntityDescriptor", 0, 0, 0).hash); + assert_eq!(gs.wire_settings_header.hash, gs.wire_settings_entity.hash_name()); //println!("Parsed Flycam hash: {}", gs.flycam_header.hash); assert_eq!(gs.flycam_header.hash, EntityHeader::from_name("FlyCamEntityDescriptorV0", 0, 0, 0).hash); + assert_eq!(gs.flycam_header.hash, gs.flycam_entity.hash_name()); //println!("Parsed Phycam hash: {}", gs.phycam_header.hash); assert_eq!(gs.phycam_header.hash, EntityHeader::from_name("CharacterCameraEntityDescriptorV1", 0, 0, 0).hash); + assert_eq!(gs.phycam_header.hash, gs.phycam_entity.hash_name()); + println!("{}", gs.to_string()); Ok(()) }