An unofficial collection of APIs used in FreeJam games and mods
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

101 lines
4.1KB

  1. #[cfg(feature = "techblox")]
  2. use libfj::techblox;
  3. #[cfg(feature = "techblox")]
  4. use libfj::techblox::{SerializedEntityDescriptor, Parsable, blocks, EntityHeader};
  5. #[cfg(feature = "techblox")]
  6. use std::io::{Read, Seek};
  7. #[cfg(feature = "techblox")]
  8. use std::fs::{File, OpenOptions};
  9. #[cfg(feature = "techblox")]
  10. const GAMESAVE_PATH: &str = "tests/GameSave.Techblox";
  11. #[cfg(feature = "techblox")]
  12. const GAMESAVE_PATH2: &str = "tests/GameSave2.Techblox";
  13. #[cfg(feature = "techblox")]
  14. const HASHNAMES: &[&str] = &[
  15. "StandardBlockEntityDescriptorV4",
  16. "WireEntityDescriptorMock",
  17. "GlobalWireSettingsEntityDescriptor",
  18. "FlyCamEntityDescriptorV0",
  19. "CharacterCameraEntityDescriptorV1",
  20. ];
  21. #[cfg(feature = "techblox")]
  22. #[test]
  23. fn techblox_gamesave_parse() -> Result<(), ()> {
  24. let mut f = File::open(GAMESAVE_PATH).map_err(|_| ())?;
  25. let mut buf = Vec::new();
  26. f.read_to_end(&mut buf).map_err(|_| ())?;
  27. let gs = techblox::GameSave::parse(&mut buf.as_slice()).map_err(|_| ())?;
  28. for i in 1..(gs.group_len as usize) {
  29. assert_eq!(gs.group_headers[i-1].hash, gs.group_headers[i].hash);
  30. //println!("#{} count {} vs {}", i, gs.group_headers[i-1].component_count, gs.group_headers[i].component_count);
  31. assert_eq!(gs.group_headers[i-1].component_count, gs.group_headers[i].component_count);
  32. }
  33. for i in 0..(gs.group_len as usize) {
  34. assert_eq!(gs.group_headers[i].component_count, techblox::BlockGroupEntity::serialized_components());
  35. }
  36. for i in 1..(gs.cube_len as usize) {
  37. //assert_eq!(gs.cube_headers[i-1].hash, gs.cube_headers[i].hash);
  38. //println!("#{} count {} vs {}", i, gs.cube_headers[i-1].component_count, gs.cube_headers[i].component_count);
  39. if gs.cube_headers[i-1].hash == gs.cube_headers[i].hash {
  40. assert_eq!(gs.group_headers[i-1].component_count, gs.group_headers[i].component_count);
  41. }
  42. }
  43. for i in 0..(gs.cube_len as usize) {
  44. assert!(gs.cube_headers[i].component_count >= blocks::BlockEntity::serialized_components());
  45. //println!("#{} components: {}", i, gs.cube_headers[i].component_count);
  46. }
  47. //println!("Parsed wire settings hash: {} obsolete? {}", gs.wire_settings_header.hash, gs.wire_settings_entity.settings_component.obsolete != 0);
  48. assert_eq!(gs.wire_settings_header.hash, EntityHeader::from_name("GlobalWireSettingsEntityDescriptor", 0, 0, 0).hash);
  49. //println!("Parsed Flycam hash: {}", gs.flycam_header.hash);
  50. assert_eq!(gs.flycam_header.hash, EntityHeader::from_name("FlyCamEntityDescriptorV0", 0, 0, 0).hash);
  51. //println!("Parsed Phycam hash: {}", gs.phycam_header.hash);
  52. assert_eq!(gs.phycam_header.hash, EntityHeader::from_name("CharacterCameraEntityDescriptorV1", 0, 0, 0).hash);
  53. println!("{}", gs.to_string());
  54. Ok(())
  55. }
  56. #[allow(dead_code)]
  57. #[cfg(feature = "techblox")]
  58. //#[test]
  59. fn techblox_gamesave_brute_force() -> Result<(), ()> {
  60. // this is slow and not very important, so it's probably better to not test this
  61. let mut f = File::open(GAMESAVE_PATH).map_err(|_| ())?;
  62. let mut buf = Vec::new();
  63. f.read_to_end(&mut buf).map_err(|_| ())?;
  64. let gs = techblox::GameSave::parse(&mut buf.as_slice()).map_err(|_| ())?;
  65. println!("murmurhash3: {} -> {}", gs.group_headers[0].guess_name(), gs.group_headers[0].hash);
  66. Ok(())
  67. }
  68. #[cfg(feature = "techblox")]
  69. #[test]
  70. fn hash_tb_name() {
  71. for name in HASHNAMES {
  72. println!("MurmurHash3: {} -> {}", name, crate::techblox::EntityHeader::from_name(name, 0, 0, 0).hash);
  73. }
  74. }
  75. #[cfg(feature = "techblox")]
  76. #[test]
  77. fn techblox_gamesave_perfect_parse() -> Result<(), ()> {
  78. let mut in_file = File::open(GAMESAVE_PATH).map_err(|_| ())?;
  79. let mut buf = Vec::new();
  80. in_file.read_to_end(&mut buf).map_err(|_| ())?;
  81. let gs = techblox::GameSave::parse(&mut buf.as_slice()).map_err(|_| ())?;
  82. let mut out_file = OpenOptions::new()
  83. .write(true)
  84. .truncate(true)
  85. .create(true)
  86. .open(GAMESAVE_PATH2)
  87. .map_err(|_| ())?;
  88. gs.dump(&mut out_file).map_err(|_| ())?;
  89. assert_eq!(in_file.stream_position().unwrap(), out_file.stream_position().unwrap());
  90. Ok(())
  91. }