arkparse 0.3.9__tar.gz → 0.4.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (180) hide show
  1. {arkparse-0.3.9 → arkparse-0.4.1}/.gitignore +2 -1
  2. {arkparse-0.3.9 → arkparse-0.4.1}/PKG-INFO +1 -1
  3. {arkparse-0.3.9 → arkparse-0.4.1}/pyproject.toml +1 -1
  4. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/api/dino_api.py +8 -3
  5. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/api/equipment_api.py +25 -7
  6. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/api/json_api.py +28 -0
  7. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/api/player_api.py +53 -2
  8. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/api/stackable_api.py +9 -3
  9. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/classes/equipment.py +31 -4
  10. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/logging/ark_save_logger.py +4 -1
  11. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/object_model/ark_game_object.py +46 -6
  12. arkparse-0.4.1/src/arkparse/object_model/cluster_data/ark_cluster_data.py +52 -0
  13. arkparse-0.4.1/src/arkparse/object_model/cluster_data/cluster_data_dino.py +63 -0
  14. arkparse-0.4.1/src/arkparse/object_model/cluster_data/cluster_data_item.py +67 -0
  15. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/object_model/cryopods/cryopod.py +61 -13
  16. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/object_model/dinos/dino.py +2 -1
  17. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/object_model/dinos/pedigree.py +3 -4
  18. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/object_model/dinos/stats.py +13 -13
  19. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/object_model/dinos/tamed_dino.py +5 -1
  20. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/object_model/equipment/__equipment_with_armor.py +3 -1
  21. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/object_model/equipment/__equipment_with_durability.py +5 -3
  22. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/object_model/misc/inventory_item.py +12 -2
  23. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/parsing/_legacy_parsing/_property_parser.py +17 -0
  24. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/parsing/_legacy_parsing/ark_property.py +3 -0
  25. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/parsing/_property_parser.py +4 -2
  26. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/parsing/ark_archive.py +13 -6
  27. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/parsing/ark_object.py +46 -2
  28. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/parsing/ark_property.py +12 -5
  29. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/parsing/ark_property_container.py +53 -0
  30. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/parsing/struct/ark_custom_item_data.py +33 -5
  31. arkparse-0.4.1/src/arkparse/parsing/struct/ark_item_craft_queue_entry.py +39 -0
  32. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/parsing/struct/object_reference.py +10 -1
  33. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/player/ark_player.py +5 -3
  34. arkparse-0.4.1/src/arkparse/player/ark_tribute_item.py +19 -0
  35. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/saves/save_connection.py +5 -6
  36. {arkparse-0.3.9 → arkparse-0.4.1}/LICENSE +0 -0
  37. {arkparse-0.3.9 → arkparse-0.4.1}/README.md +0 -0
  38. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/__init__.py +0 -0
  39. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/api/__init__.py +0 -0
  40. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/api/base_api.py +0 -0
  41. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/api/general_api.py +0 -0
  42. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/api/rcon_api.py +0 -0
  43. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/api/structure_api.py +0 -0
  44. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/ark_tribe.py +0 -0
  45. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/assets/ABERRATION.PNG +0 -0
  46. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/assets/RAGNAROK.PNG +0 -0
  47. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/assets/THE_ISLAND.PNG +0 -0
  48. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/assets/__init__.py +0 -0
  49. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/assets/heavy_inventory +0 -0
  50. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/assets/tamable_dinos.txt +0 -0
  51. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/assets/templates/equipment/armor +0 -0
  52. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/assets/templates/equipment/armor_bp +0 -0
  53. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/assets/templates/equipment/armor_bp_n.json +0 -0
  54. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/assets/templates/equipment/armor_n.json +0 -0
  55. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/assets/templates/equipment/saddle +0 -0
  56. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/assets/templates/equipment/saddle_bp +0 -0
  57. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/assets/templates/equipment/saddle_bp_n.json +0 -0
  58. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/assets/templates/equipment/saddle_n.json +0 -0
  59. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/assets/templates/equipment/shield +0 -0
  60. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/assets/templates/equipment/shield_bp +0 -0
  61. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/assets/templates/equipment/shield_bp_n.json +0 -0
  62. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/assets/templates/equipment/shield_n.json +0 -0
  63. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/assets/templates/equipment/weapon +0 -0
  64. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/assets/templates/equipment/weapon_bp +0 -0
  65. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/assets/templates/equipment/weapon_bp_n.json +0 -0
  66. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/assets/templates/equipment/weapon_n.json +0 -0
  67. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/assets/templates/inventory/with_item_n.json +0 -0
  68. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/assets/templates/stackable/stackable +0 -0
  69. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/assets/templates/stackable/stackable_n.json +0 -0
  70. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/classes/__init__.py +0 -0
  71. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/classes/consumables.py +0 -0
  72. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/classes/dinos.py +0 -0
  73. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/classes/placed_structures.py +0 -0
  74. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/classes/player.py +0 -0
  75. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/classes/resources.py +0 -0
  76. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/enums/__init__.py +0 -0
  77. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/enums/ark_dino_trait.py +0 -0
  78. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/enums/ark_enum.py +0 -0
  79. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/enums/ark_equipment_stat.py +0 -0
  80. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/enums/ark_item_quality.py +0 -0
  81. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/enums/ark_map.py +0 -0
  82. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/enums/ark_stat.py +0 -0
  83. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/ftp/__init__.py +0 -0
  84. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/ftp/ark_ftp_client.py +0 -0
  85. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/helpers/dino/is_wild_tamed.py +0 -0
  86. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/logging/__init__.py +0 -0
  87. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/object_model/bases/base.py +0 -0
  88. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/object_model/dinos/__init__.py +0 -0
  89. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/object_model/dinos/baby.py +0 -0
  90. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/object_model/dinos/dino_ai_controller.py +0 -0
  91. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/object_model/dinos/dino_id.py +0 -0
  92. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/object_model/dinos/tamed_baby.py +0 -0
  93. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/object_model/equipment/__armor_defaults.py +0 -0
  94. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/object_model/equipment/__equipment.py +0 -0
  95. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/object_model/equipment/__init__.py +0 -0
  96. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/object_model/equipment/armor.py +0 -0
  97. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/object_model/equipment/saddle.py +0 -0
  98. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/object_model/equipment/shield.py +0 -0
  99. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/object_model/equipment/weapon.py +0 -0
  100. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/object_model/misc/__parsed_object_base.py +0 -0
  101. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/object_model/misc/dino_owner.py +0 -0
  102. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/object_model/misc/inventory.py +0 -0
  103. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/object_model/misc/object_crafter.py +0 -0
  104. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/object_model/misc/object_owner.py +0 -0
  105. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/object_model/stackables/__init__.py +0 -0
  106. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/object_model/stackables/_stackable.py +0 -0
  107. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/object_model/stackables/ammo.py +0 -0
  108. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/object_model/stackables/resource.py +0 -0
  109. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/object_model/structures/__init__.py +0 -0
  110. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/object_model/structures/structure.py +0 -0
  111. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/object_model/structures/structure_with_inventory.py +0 -0
  112. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/parsing/__init__.py +0 -0
  113. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/parsing/_base_value_parser.py +0 -0
  114. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/parsing/_base_value_validator.py +0 -0
  115. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/parsing/_binary_reader_base.py +0 -0
  116. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/parsing/_byte_operator.py +0 -0
  117. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/parsing/_legacy_parsing/__init__.py +0 -0
  118. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/parsing/_legacy_parsing/_property_insertor.py +0 -0
  119. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/parsing/_legacy_parsing/_property_replacer.py +0 -0
  120. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/parsing/_legacy_parsing/ark_binary_parser.py +0 -0
  121. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/parsing/_legacy_parsing/struct/__init__.py +0 -0
  122. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/parsing/_legacy_parsing/struct/ark_dino_ancestor_entry.py +0 -0
  123. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/parsing/_legacy_parsing/struct/ark_item_net_id.py +0 -0
  124. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/parsing/_legacy_parsing/struct/ark_my_persistent_buff_datas.py +0 -0
  125. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/parsing/_legacy_parsing/struct/ark_object_property.py +0 -0
  126. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/parsing/_legacy_parsing/struct/ark_struct_type.py +0 -0
  127. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/parsing/_legacy_parsing/struct/ark_tracked_actor_id_category_pair_with_bool.py +0 -0
  128. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/parsing/_legacy_parsing/struct/ark_unique_net_id_repl.py +0 -0
  129. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/parsing/_legacy_parsing/struct/ark_vector.py +0 -0
  130. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/parsing/_legacy_parsing/struct/ark_vector_bool_pair.py +0 -0
  131. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/parsing/_property_insertor.py +0 -0
  132. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/parsing/_property_replacer.py +0 -0
  133. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/parsing/ark_binary_parser.py +0 -0
  134. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/parsing/ark_set.py +0 -0
  135. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/parsing/ark_value_type.py +0 -0
  136. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/parsing/array_property.py +0 -0
  137. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/parsing/game_object_reader_configuration.py +0 -0
  138. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/parsing/struct/__init__.py +0 -0
  139. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/parsing/struct/actor_transform.py +0 -0
  140. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/parsing/struct/ark_color.py +0 -0
  141. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/parsing/struct/ark_crafting_resource_requirement.py +0 -0
  142. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/parsing/struct/ark_dino_ancestor_entry.py +0 -0
  143. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/parsing/struct/ark_dino_order_id.py +0 -0
  144. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/parsing/struct/ark_gacha_resource_struct.py +0 -0
  145. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/parsing/struct/ark_gene_trait_struct.py +0 -0
  146. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/parsing/struct/ark_gigantoraptor_bonded_struct.py +0 -0
  147. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/parsing/struct/ark_int_point.py +0 -0
  148. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/parsing/struct/ark_item_net_id.py +0 -0
  149. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/parsing/struct/ark_key_value_pair.py +0 -0
  150. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/parsing/struct/ark_linear_color.py +0 -0
  151. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/parsing/struct/ark_my_persistent_buff_datas.py +0 -0
  152. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/parsing/struct/ark_object_property.py +0 -0
  153. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/parsing/struct/ark_painting_key_value.py +0 -0
  154. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/parsing/struct/ark_player_death_reason.py +0 -0
  155. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/parsing/struct/ark_primal_saddle_structure.py +0 -0
  156. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/parsing/struct/ark_quat.py +0 -0
  157. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/parsing/struct/ark_rotator.py +0 -0
  158. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/parsing/struct/ark_server_custom_folder.py +0 -0
  159. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/parsing/struct/ark_struct_type.py +0 -0
  160. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/parsing/struct/ark_tracked_actor_id_category_pair.py +0 -0
  161. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/parsing/struct/ark_tracked_actor_id_category_pair_with_bool.py +0 -0
  162. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/parsing/struct/ark_tribe_alliance.py +0 -0
  163. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/parsing/struct/ark_tribe_rank_group.py +0 -0
  164. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/parsing/struct/ark_unique_net_id_repl.py +0 -0
  165. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/parsing/struct/ark_vector.py +0 -0
  166. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/parsing/struct/ark_vector_bool_pair.py +0 -0
  167. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/parsing/struct/unknown_struct.py +0 -0
  168. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/player/ark_character_config.py +0 -0
  169. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/player/ark_character_stats.py +0 -0
  170. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/player/ark_persistent_buff_data.py +0 -0
  171. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/saves/__init__.py +0 -0
  172. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/saves/asa_save.py +0 -0
  173. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/saves/header_location.py +0 -0
  174. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/saves/save_context.py +0 -0
  175. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/utils/__init__.py +0 -0
  176. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/utils/heatmap_visualization.py +0 -0
  177. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/utils/import_file.py +0 -0
  178. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/utils/json_utils.py +0 -0
  179. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/utils/map_images.py +0 -0
  180. {arkparse-0.3.9 → arkparse-0.4.1}/src/arkparse/utils/tm_files.py +0 -0
@@ -183,4 +183,5 @@ temp
183
183
  **/temp_files/**
184
184
  **/temp_files**
185
185
  **/exports/**
186
- **/**.ark.gz
186
+ **/**.ark.gz
187
+ /src/.idea
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: arkparse
3
- Version: 0.3.9
3
+ Version: 0.4.1
4
4
  Summary: A package to parse and modify ark save files
5
5
  Project-URL: Homepage, https://github.com/VincentHenauGithub/ark-save-parser
6
6
  Author-email: Vincent Henau <vincent.henau.github@gmail.com>
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "arkparse"
7
- version = "0.3.9"
7
+ version = "0.4.1"
8
8
  dependencies = [
9
9
  "rcon>=2.4.9",
10
10
  "numpy>=2.3.2",
@@ -29,13 +29,18 @@ class DinoApi:
29
29
  blueprint_name_filter=lambda name: \
30
30
  name is not None and \
31
31
  (("Dinos/" in name and "_Character_" in name) or \
32
- ("PrimalItem_WeaponEmptyCryopod" in name)))
32
+ ("PrimalItem_WeaponEmptyCryopod" in name or "PrimalItem_SCSCryopod" in name)))
33
33
 
34
34
  def __init__(self, save: AsaSave):
35
35
  self.save = save
36
36
  self.all_objects = None
37
37
  self.parsed_dinos: Dict[UUID, Dino] = {}
38
38
  self.parsed_cryopods: Dict[UUID, Cryopod] = {}
39
+
40
+ @staticmethod
41
+ def is_applicable_bp(blueprint: str) -> bool:
42
+ return DinoApi._DEFAULT_CONFIG.blueprint_name_filter(blueprint)
43
+
39
44
  def get_all_objects(self, config: GameObjectReaderConfiguration = None) -> Dict[UUID, ArkGameObject]:
40
45
  reuse = False
41
46
 
@@ -114,7 +119,7 @@ class DinoApi:
114
119
  dino = Dino(obj.uuid, save=self.save)
115
120
  self.parsed_dinos[obj.uuid] = dino
116
121
 
117
- elif "PrimalItem_WeaponEmptyCryopod" in obj.blueprint and include_cryos and include_tamed:
122
+ elif ("PrimalItem_SCSCryopod" in obj.blueprint or "PrimalItem_WeaponEmptyCryopod" in obj.blueprint) and include_cryos and include_tamed:
118
123
  if not obj.get_property_value("bIsEngram", default=False) and obj.get_property_value("CustomItemDatas") is not None:
119
124
  if obj.uuid in self.parsed_cryopods:
120
125
  is_baby = self.parsed_cryopods[obj.uuid].dino is not None and isinstance(self.parsed_cryopods[obj.uuid].dino, TamedBaby)
@@ -203,7 +208,7 @@ class DinoApi:
203
208
 
204
209
  def get_all_by_class(self, class_names: List[str], include_cryopodded: bool = True) -> Dict[UUID, Dino]:
205
210
  config = GameObjectReaderConfiguration(
206
- blueprint_name_filter=lambda name: name is not None and ((name in class_names) or (include_cryopodded and ("PrimalItem_WeaponEmptyCryopod" in name)))
211
+ blueprint_name_filter=lambda name: name is not None and ((name in class_names) or (include_cryopodded and ("PrimalItem_WeaponEmptyCryopod" in name or "PrimalItem_SCSCryopod" in name)))
207
212
  )
208
213
 
209
214
  dinos = self.get_all(config, include_cryos=include_cryopodded)
@@ -16,6 +16,13 @@ from arkparse.classes.equipment import Equipment as EqClasses
16
16
  from .general_api import GeneralApi
17
17
 
18
18
  class EquipmentApi(GeneralApi):
19
+ _DEFAULT_CONFIG = GameObjectReaderConfiguration(
20
+ blueprint_name_filter=lambda name: name is not None and \
21
+ (("Weapons" in name and ("PrimalItemAmmo" not in name) and ("PrimalItem_WeaponEmptyCryopod" not in name)) or \
22
+ "Armor" in name or \
23
+ name in (EqClasses.weapons.all_bps + EqClasses.shield.all_bps + EqClasses.saddles.all_bps + EqClasses.armor.all_bps))
24
+ )
25
+
19
26
  class Classes:
20
27
  WEAPON = Weapon
21
28
  SADDLE = Saddle
@@ -23,16 +30,27 @@ class EquipmentApi(GeneralApi):
23
30
  SHIELD = Shield
24
31
 
25
32
  def __init__(self, save: AsaSave):
26
- config = GameObjectReaderConfiguration(
27
- blueprint_name_filter=lambda name: name is not None and \
28
- (("Weapons" in name and "PrimalItemAmmo" not in name) or \
29
- "Armor" in name or \
30
- name in EqClasses.all_bps)
31
-
32
- )
33
+ config = EquipmentApi._DEFAULT_CONFIG
33
34
  super().__init__(save, config)
34
35
  self.parsed_objects: Dict[UUID, Equipment] = {}
35
36
 
37
+ @staticmethod
38
+ def bp_to_class(blueprint: str):
39
+ if blueprint in EqClasses.weapons.all_bps or ("/Weapons/" in blueprint):
40
+ return EquipmentApi.Classes.WEAPON
41
+ elif blueprint in EqClasses.saddles.all_bps or ("/Saddles/" in blueprint):
42
+ return EquipmentApi.Classes.SADDLE
43
+ elif blueprint in EqClasses.shield.all_bps or ("/Armor/Shields/" in blueprint):
44
+ return EquipmentApi.Classes.SHIELD
45
+ elif blueprint in EqClasses.armor.all_bps or ("/Armor/" in blueprint):
46
+ return EquipmentApi.Classes.ARMOR
47
+ else:
48
+ return None
49
+
50
+ @staticmethod
51
+ def is_applicable_bp(blueprint: str) -> bool:
52
+ return EquipmentApi._DEFAULT_CONFIG.blueprint_name_filter(blueprint)
53
+
36
54
  def __get_cls_filter(self, cls: "EquipmentApi.Classes"):
37
55
  if cls == self.Classes.WEAPON:
38
56
  return EqClasses.weapons.all_bps
@@ -320,6 +320,33 @@ class JsonApi:
320
320
 
321
321
  ArkSaveLogger.api_log("Players successfully exported.")
322
322
 
323
+ def export_cluster_data(self, player_api: PlayerApi = None, cluster_data_dir: str = None, export_folder_path: str = Path.cwd() / "json_exports"):
324
+ ArkSaveLogger.api_log("Exporting cluster data...")
325
+
326
+ # Get player API if not provided.
327
+ if player_api is None:
328
+ player_api = PlayerApi(self.save, self.ignore_error, cluster_data_dir=cluster_data_dir)
329
+
330
+ all_cluster_data = []
331
+ for unique_id, cluster_data in player_api.cluster_data.items():
332
+ cluster_data_json_obj = {
333
+ "PlayerUniqueID": unique_id.__str__(),
334
+ "Dinos": [dino.to_json_obj() for dino in cluster_data.dinos],
335
+ "Items": [item.to_json_obj() for item in cluster_data.items]
336
+ }
337
+ all_cluster_data.append(cluster_data_json_obj)
338
+
339
+ # Create json exports folder if it does not exist.
340
+ path_obj = Path(cluster_data_dir) if cluster_data_dir is not None else Path(export_folder_path)
341
+ if not (path_obj.exists() and path_obj.is_dir()):
342
+ path_obj.mkdir(parents=True, exist_ok=True)
343
+
344
+ # Write JSON.
345
+ with open(path_obj / "cluster_data.json", "w") as text_file:
346
+ text_file.write(json.dumps(all_cluster_data, default=lambda o: o.to_json_obj() if hasattr(o, 'to_json_obj') else None, indent=4, cls=DefaultJsonEncoder))
347
+
348
+ ArkSaveLogger.api_log("Cluster data successfully exported.")
349
+
323
350
  def export_tribes(self, player_api: PlayerApi = None, export_folder_path: str = Path.cwd() / "json_exports", include_players_data: bool = False):
324
351
  ArkSaveLogger.api_log("Exporting tribes...")
325
352
 
@@ -506,3 +533,4 @@ class JsonApi:
506
533
  self.export_player_pawns(player_api=player_api, export_folder_path=export_folder_path)
507
534
  self.export_players(player_api=player_api, export_folder_path=export_folder_path)
508
535
  self.export_tribes(player_api=player_api, export_folder_path=export_folder_path)
536
+ self.export_cluster_data(player_api=player_api, export_folder_path=export_folder_path)
@@ -1,5 +1,5 @@
1
1
  import uuid
2
- from typing import List, Dict, Optional
2
+ from typing import List, Dict, Optional, TYPE_CHECKING
3
3
  from pathlib import Path
4
4
  from uuid import UUID
5
5
 
@@ -17,6 +17,9 @@ from arkparse.object_model.misc.dino_owner import DinoOwner
17
17
  from arkparse.object_model.misc.object_owner import ObjectOwner
18
18
  from arkparse.object_model.ark_game_object import ArkGameObject
19
19
 
20
+ if TYPE_CHECKING:
21
+ from arkparse.object_model.cluster_data.ark_cluster_data import ClusterData
22
+
20
23
  class _TribeAndPlayerData:
21
24
  HEADER_OFFSET_ADJUSTMENT = 4
22
25
  TRIBE_HEADER_BASE_OFFSET = 4
@@ -121,12 +124,13 @@ class PlayerApi:
121
124
  OBJECT = 0
122
125
  DINO = 1
123
126
 
124
- def __init__(self, save: AsaSave, ignore_error: bool = False, no_pawns: bool = False, bypass_inventory: bool = False, pawn_objects: Optional[list[ArkGameObject]] = None, force_legacy_store: bool = False):
127
+ def __init__(self, save: AsaSave, ignore_error: bool = False, no_pawns: bool = False, bypass_inventory: bool = False, pawn_objects: Optional[list[ArkGameObject]] = None, force_legacy_store: bool = False, cluster_data_dir: Optional[Path] = None):
125
128
  self.players: List[ArkPlayer] = []
126
129
  self.tribes: List[ArkTribe] = []
127
130
  self.tribe_to_player_map: Dict[int, List[ArkPlayer]] = {}
128
131
  self.save: AsaSave = save
129
132
  self.pawns: Optional[Dict[UUID, ArkGameObject]] = None
133
+ self.cluster_data: Optional[Dict[str, "ClusterData"]] = {}
130
134
 
131
135
  self.profile_paths: List[Path] = []
132
136
  self.tribe_paths: List[Path] = []
@@ -162,6 +166,8 @@ class PlayerApi:
162
166
  ArkSaveLogger.api_log("Parsing player and tribe data from files")
163
167
  self.__update_files(bypass_inventory)
164
168
 
169
+ self._get_cluster_data_from_directory(cluster_data_dir)
170
+
165
171
  def __del__(self):
166
172
  ArkSaveLogger.api_log("Stopping PlayerApi")
167
173
  self.players = {}
@@ -178,6 +184,14 @@ class PlayerApi:
178
184
  blueprint_name_filter=lambda name: name is not None and name in pawn_bps,
179
185
  )
180
186
  self.pawns = self.save.get_game_objects(config)
187
+
188
+ def __find_cluster_data_file_in_save_dir(self, player: ArkPlayer) -> Optional[Path]:
189
+ if self.save is not None and self.save.save_dir is not None:
190
+ expected_file_name = f"{player.unique_id}"
191
+ expected_path = self.save.save_dir / expected_file_name
192
+ if expected_path.exists():
193
+ return expected_path
194
+ return None
181
195
 
182
196
  def __store_as_file(self, data: bytes, file_name: str):
183
197
  output_dir = TEMP_FILES_DIR
@@ -208,6 +222,28 @@ class PlayerApi:
208
222
  self.profile_paths.append(path)
209
223
  for path in directory.glob("*.arktribe"):
210
224
  self.tribe_paths.append(path)
225
+
226
+ def _get_cluster_data_from_directory(self, directory: Path = None) -> Optional["ClusterData"]:
227
+ from arkparse.object_model.cluster_data.ark_cluster_data import ClusterData
228
+ def get_files(path: Path) -> list[Path]:
229
+ return [f for f in path.iterdir() if (f.is_file() and not f.name.endswith(".py"))]
230
+
231
+ all_data = {}
232
+ files = get_files(directory) if directory is not None else []
233
+
234
+ if len(files) == 0:
235
+ directory = self.save.save_dir if self.save is not None else None
236
+ for player in self.players:
237
+ path = self.__find_cluster_data_file_in_save_dir(player)
238
+ if path is not None:
239
+ files.append(path)
240
+
241
+ for file in files:
242
+ ArkSaveLogger.info_log(f"Found file: {file.name}")
243
+ cluster_data = ClusterData(directory, file.name)
244
+ all_data[file.name] = cluster_data
245
+
246
+ self.cluster_data = all_data
211
247
 
212
248
  def __update_files(self, bypass_inventory: bool):
213
249
  new_players: Dict[int, ArkPlayer] = {}
@@ -327,6 +363,21 @@ class PlayerApi:
327
363
  return t
328
364
  return None
329
365
 
366
+ def get_cluster_data(self, player: ArkPlayer):
367
+ if self.cluster_data is None:
368
+ return None
369
+
370
+ if player.unique_id in self.cluster_data:
371
+ return self.cluster_data[player.unique_id]
372
+ return None
373
+
374
+ def get_players_with_cluster_data(self):
375
+ players_with_data = []
376
+ for player in self.players:
377
+ if self.get_cluster_data(player) is not None:
378
+ players_with_data.append(player)
379
+ return players_with_data
380
+
330
381
  def get_player_with(self, stat: int, stat_type: int = StatType.HIGHEST):
331
382
  istat = self.__get_stat(stat)
332
383
  player: Optional[ArkPlayer] = None
@@ -13,10 +13,16 @@ class StackableApi(GeneralApi):
13
13
  RESOURCE = Resource
14
14
  AMMO = Ammo
15
15
 
16
+ _DEFAULT_CONFIG = GameObjectReaderConfiguration(
17
+ blueprint_name_filter=lambda name: name is not None and ("Resources/PrimalItemResource" in name or "/PrimalItemConsumable" in name or "PrimalItemAmmo" in name)
18
+ )
19
+
20
+ @staticmethod
21
+ def is_applicable_bp(blueprint: str) -> bool:
22
+ return StackableApi._DEFAULT_CONFIG.blueprint_name_filter(blueprint)
23
+
16
24
  def __init__(self, save: AsaSave):
17
- config = GameObjectReaderConfiguration(
18
- blueprint_name_filter=lambda name: name is not None and "Resources/PrimalItemResource" in name or "/PrimalItemConsumable" in name
19
- )
25
+ config = StackableApi._DEFAULT_CONFIG
20
26
  super().__init__(save, config)
21
27
 
22
28
  def get_all(self, cls: "StackableApi.Classes", config = None) -> Dict[UUID, InventoryItem]:
@@ -5,7 +5,7 @@ class Saddles:
5
5
  ceratosaurus: str = "/Game/ASA/Dinos/Ceratosaurus/Dinos/Saddle/PrimalItemArmor_CeratosaurusSaddle_ASA.PrimalItemArmor_CeratosaurusSaddle_ASA_C"
6
6
  deinosuchus: str = "/Game/ASA/Dinos/Deinosuchus/Saddle/PrimalItemArmor_Deinosuchus_Saddle_ASA.PrimalItemArmor_Deinosuchus_Saddle_ASA_C"
7
7
  fasolasuchus: str = "/Game/ASA/Dinos/Fasolasuchus/PrimalItemArmor_FasolaSaddle.PrimalItemArmor_FasolaSaddle_C"
8
- gigantoraptor: str = "/Game/ASA/Dinos/Gigantoraptor/PrimalItemArmor_GigantoraptorSaddle.PrimalItemArmor_GigantoraptorSaddle_C"
8
+ gigantoraptor_ASA: str = "/Game/ASA/Dinos/Gigantoraptor/PrimalItemArmor_GigantoraptorSaddle.PrimalItemArmor_GigantoraptorSaddle_C"
9
9
  shastasaurus: str = "/Game/ASA/Dinos/Shastasaurus/PrimalItemArmor_ShastaSaddle_Submarine.PrimalItemArmor_ShastaSaddle_Submarine_C"
10
10
  xiphactinus: str = "/Game/ASA/Dinos/Xiphactinus/Dinos/Saddle/PrimalItemArmor_XiphSaddle_ASA.PrimalItemArmor_XiphSaddle_ASA_C"
11
11
  helicoprion: str = "/Game/ASA/Dinos/Helicoprion/Saddle/PrimalItemArmor_Helicoprion.PrimalItemArmor_Helicoprion_C"
@@ -106,8 +106,9 @@ class Saddles:
106
106
  ravager: str = "/Game/Aberration/Dinos/CaveWolf/PrimalItemArmor_CavewolfPromoSaddle.PrimalItemArmor_CavewolfPromoSaddle_C"
107
107
  managarmr: str = "/Game/Extinction/CoreBlueprints/Items/Saddle/PrimalItemArmor_IceJumperSaddle.PrimalItemArmor_IceJumperSaddle_C"
108
108
  velonosaur: str = "/Game/Extinction/CoreBlueprints/Items/Saddle/PrimalItemArmor_SpindlesSaddle.PrimalItemArmor_SpindlesSaddle_C"
109
+ gigantoraptor: str = "/Gigantoraptor/Gigantoraptor/PrimalItemArmor_GigantoraptorSaddle.PrimalItemArmor_GigantoraptorSaddle_C"
109
110
 
110
- all_bps = [yi_ling, archelon, ceratosaurus, deinosuchus, fasolasuchus, gigantoraptor,
111
+ all_bps = [yi_ling, archelon, ceratosaurus, deinosuchus, fasolasuchus, gigantoraptor_ASA,
111
112
  shastasaurus, xiphactinus, saddle_cart_btt, rockdrake_btt, allo, ankylo,
112
113
  argentavis, arthro, baryonyx, basilo, castoroides, carcha, carno, chalico,
113
114
  daeodon, diplodocus, dire_bear, doedi, dolphin, dunkleosteus, equus, gallimimus,
@@ -120,7 +121,7 @@ class Saddles:
120
121
  titanosaur_platform, beelzebufo, trike, carbo, tuso, yuty, basilisk, cave_wolf,
121
122
  karkinos, mole_rat, rock_drake, rock_drake_tek, camel, mantis, moth, rock_golem,
122
123
  thorny_dragon, bison, deinotherium, dreadnoughtus, maelizard, gacha, gas_bags,
123
- snow_owl, ravager, managarmr, velonosaur, helicoprion]
124
+ snow_owl, ravager, managarmr, velonosaur, helicoprion, gigantoraptor]
124
125
 
125
126
  class Hazard:
126
127
  boots: str = "/Game/Aberration/CoreBlueprints/Items/Armor/HazardSuit/PrimalItemArmor_HazardSuitBoots.PrimalItemArmor_HazardSuitBoots_C"
@@ -350,6 +351,30 @@ class Weapons:
350
351
 
351
352
  all_bps = gathering.all_bps + primitive.all_bps + advanced.all_bps
352
353
 
354
+ class Mek:
355
+ shield: str = "/Game/Extinction/CoreBlueprints/Items/Saddle/PrimalItemArmor_MekBackpack_Shield.PrimalItemArmor_MekBackpack_Shield_C"
356
+ cannon: str = "/Game/Extinction/CoreBlueprints/Items/Saddle/PrimalItemArmor_MekBackpack_SiegeCannon.PrimalItemArmor_MekBackpack_SiegeCannon_C"
357
+ missile_pod: str = "/Game/Extinction/CoreBlueprints/Items/Saddle/PrimalItemArmor_MekBackpack_MissilePod.PrimalItemArmor_MekBackpack_MissilePod_C"
358
+ transformer: str = "/Game/Extinction/CoreBlueprints/Items/Saddle/PrimalItemArmor_MekTransformer.PrimalItemArmor_MekTransformer_C"
359
+
360
+ all_bps = [shield, cannon]
361
+
362
+ class ArmaDoggoGear:
363
+ armor: str = "/Game/Packs/Wasteland/Dinos/Doggo/PrimalItemArmor_DinoCompanionSaddle_Doggo.PrimalItemArmor_DinoCompanionSaddle_Doggo_C"
364
+ ammo_box: str = "/Game/Packs/Wasteland/Dinos/CompanionDino/Items/Armor/PrimalItemArmor_DinoCompanion_Gear_AmmoBox.PrimalItemArmor_DinoCompanion_Gear_AmmoBox_C"
365
+ extra_armor: str = "/Game/Packs/Wasteland/Dinos/CompanionDino/Items/Armor/PrimalItemArmor_DinoCompanion_Gear_ExtraArmor.PrimalItemArmor_DinoCompanion_Gear_ExtraArmor_C"
366
+ speed_booster: str = "/Game/Packs/Wasteland/Dinos/CompanionDino/Items/Armor/PrimalItemArmor_DinoCompanion_Gear_Movespeed.PrimalItemArmor_DinoCompanion_Gear_Movespeed_C"
367
+ oxygen_tank: str = "/Game/Packs/Wasteland/Dinos/CompanionDino/Items/Armor/PrimalItemArmor_DinoCompanion_Gear_OxygenTank.PrimalItemArmor_DinoCompanion_Gear_OxygenTank_C"
368
+ rucksack: str = "/Game/Packs/Wasteland/Dinos/CompanionDino/Items/Armor/PrimalItemArmor_DinoCompanion_Gear_Bag.PrimalItemArmor_DinoCompanion_Gear_Bag_C"
369
+ medpack: str = "/Game/Packs/Wasteland/Dinos/CompanionDino/Items/Armor/PrimalItemArmor_DinoCompanion_Gear_Medkit.PrimalItemArmor_DinoCompanion_Gear_Medkit_C"
370
+ camping_gear: str = "/Game/Packs/Wasteland/Dinos/CompanionDino/Items/Armor/PrimalItemArmor_DinoCompanion_Gear_RolledUpSleepingBag.PrimalItemArmor_DinoCompanion_Gear_RolledUpSleepingBag_C"
371
+ picnic_set: str = "/Game/Packs/Wasteland/Dinos/CompanionDino/Items/Armor/PrimalItemArmor_DinoCompanion_Gear_FoodBasket.PrimalItemArmor_DinoCompanion_Gear_FoodBasket_C"
372
+ battle_spikes: str = "\Game\Packs\Wasteland\Dinos\CompanionDino\Items\Armor\PrimalItemArmor_DinoCompanion_Gear_Spikes.PrimalItemArmor_DinoCompanion_Gear_Spikes_C"
373
+ bait_trap: str = "/Game/Packs/Wasteland/Dinos/CompanionDino/Items/Armor/PrimalItemArmor_DinoCompanion_Gear_MeatSack.PrimalItemArmor_DinoCompanion_Gear_MeatSack_C"
374
+
375
+
376
+
377
+ all_bps = [armor]
353
378
 
354
379
  class Equipment:
355
380
  saddles = Saddles()
@@ -360,5 +385,7 @@ class Equipment:
360
385
  ammo = Ammo()
361
386
  misc: Misc = Misc()
362
387
  throwables: Throwables = Throwables()
388
+ mek: Mek = Mek()
389
+ arma_doggo_gear: ArmaDoggoGear = ArmaDoggoGear()
363
390
 
364
- all_bps = saddles.all_bps + armor.all_bps + utilities.all_bps + weapons.all_bps + shield.all_bps + ammo.all_bps + misc.all_bps + throwables.all_bps
391
+ all_bps = saddles.all_bps + armor.all_bps + utilities.all_bps + weapons.all_bps + shield.all_bps + ammo.all_bps + misc.all_bps + throwables.all_bps + mek.all_bps + arma_doggo_gear.all_bps
@@ -48,7 +48,10 @@ class ArkSaveLogger:
48
48
 
49
49
  @staticmethod
50
50
  def parser_log(message: str):
51
- ArkSaveLogger.__log(message, ArkSaveLogger.LogTypes.PARSER, ArkSaveLogger.LogColors.CYAN)
51
+ struct_header = ""
52
+ for struct in ArkSaveLogger.current_struct_path:
53
+ struct_header += f"[{struct}]"
54
+ ArkSaveLogger.__log(struct_header + message, ArkSaveLogger.LogTypes.PARSER, ArkSaveLogger.LogColors.CYAN)
52
55
 
53
56
  @staticmethod
54
57
  def info_log(message: str):
@@ -39,6 +39,9 @@ class ArkGameObject(ArkPropertyContainer):
39
39
 
40
40
  def __init__(self, uuid: Optional[UUID] = None, blueprint: Optional[str] = None, binary_reader: Optional[ArkBinaryParser|LegacyArkBinaryParser] = None, from_custom_bytes: bool = False, no_header: bool = False):
41
41
  self.parser_type = ArkProperty if (isinstance(binary_reader, ArkBinaryParser) or binary_reader is None) else LegacyArkProperty
42
+ self.uuid = uuid
43
+ self.blueprint = blueprint
44
+ string_name = False
42
45
  super().__init__()
43
46
  if binary_reader:
44
47
  ArkSaveLogger.set_file(binary_reader, "debug.bin")
@@ -49,7 +52,8 @@ class ArkGameObject(ArkPropertyContainer):
49
52
  self.uuid2: UUID = None
50
53
  binary_reader.set_position(0)
51
54
 
52
- self.blueprint = binary_reader.read_name()
55
+ self.blueprint, string_name = ArkGameObject.read_name(uuid, binary_reader)
56
+ ArkSaveLogger.parser_log(f"Read Blueprint: {self.blueprint} (String name: {string_name})")
53
57
 
54
58
  sContext : SaveContext = binary_reader.save_context
55
59
  self.location = sContext.get_actor_transform(uuid) or None
@@ -58,11 +62,14 @@ class ArkGameObject(ArkPropertyContainer):
58
62
  self.uuid = binary_reader.read_uuid()
59
63
  self.blueprint = binary_reader.read_string()
60
64
  ArkSaveLogger.parser_log(f"Read UUID: {self.uuid}, Blueprint: {self.blueprint}")
61
-
65
+
62
66
  binary_reader.validate_uint32(0)
67
+ if string_name:
68
+ binary_reader.read_uint16()
63
69
 
64
70
  try:
65
- if not no_header:
71
+ if not (no_header or string_name):
72
+ ArkSaveLogger.parser_log(f"Reading names for object {self.blueprint} ({self.uuid})")
66
73
  offsets = []
67
74
  if not from_custom_bytes:
68
75
  nr_names = binary_reader.read_int()
@@ -97,7 +104,8 @@ class ArkGameObject(ArkPropertyContainer):
97
104
  ArkSaveLogger.parser_log(f"Properties offset: {self.properties_offset}")
98
105
  binary_reader.validate_uint32(0)
99
106
 
100
- if not from_custom_bytes:
107
+ if not from_custom_bytes:
108
+ ArkSaveLogger.parser_log(f"Reading properties for object {self.blueprint} ({self.uuid})")
101
109
  self.read_properties(binary_reader, self.parser_type, binary_reader.size())
102
110
 
103
111
  if binary_reader.size() - binary_reader.position >= 20:
@@ -111,7 +119,9 @@ class ArkGameObject(ArkPropertyContainer):
111
119
  raise Exception("Unknown data left")
112
120
 
113
121
  if no_header:
114
- self.blueprint = self.get_property_value("ItemArchetype").value
122
+ bp_ref = self.get_property_value("ItemArchetype", None)
123
+ if bp_ref is not None:
124
+ self.blueprint = bp_ref.value
115
125
  except Exception as e:
116
126
  ArkSaveLogger.error_log(f"Error while reading object {self.blueprint} ({self.uuid}): {e}")
117
127
  ArkSaveLogger.set_file(binary_reader, "debug.bin")
@@ -227,6 +237,33 @@ class ArkGameObject(ArkPropertyContainer):
227
237
  buffer.validate_uint32(0)
228
238
  return name
229
239
 
240
+ @staticmethod
241
+ def read_name(obj_uuid: UUID, reader: ArkBinaryParser) -> str:
242
+ reader.set_position(0)
243
+ string_name = False
244
+
245
+ try:
246
+ class_name = reader.read_name()
247
+ except Exception as e:
248
+ # Check for string name instead of name table reference, this sometimes happens since Lost Colony
249
+ # To be ivestigated why this happens
250
+ reader.set_position(0)
251
+ try:
252
+ unknow_id = reader.read_uint32()
253
+ reader.validate_uint64(0)
254
+ reader.validate_uint32(1)
255
+ class_name = reader.read_string()
256
+ # reader.validate_uint32(0)
257
+ string_name = True
258
+ ArkSaveLogger.parser_log(f"Object {obj_uuid} has string class name {class_name} instead of name table reference")
259
+ except Exception as e:
260
+ ArkSaveLogger.error_log(f"Error reading class name for object {obj_uuid}: {e}")
261
+ reader.structured_print(to_default_file=True)
262
+ input("Press Enter to continue...")
263
+ class_name = "UnknownClass"
264
+
265
+ return class_name, string_name
266
+
230
267
  def get_short_name(self) -> str:
231
268
  to_strip_end = [
232
269
  "_C",
@@ -262,4 +299,7 @@ class ArkGameObject(ArkPropertyContainer):
262
299
  if short.startswith(strip):
263
300
  short = short[len(strip):]
264
301
 
265
- return short
302
+ return short
303
+
304
+ def __str__(self):
305
+ return f"ArkGameObject(UUID: {self.uuid}, Blueprint: {self.blueprint}, Location: {self.location}, Properties: {len(self.properties)} properties)"
@@ -0,0 +1,52 @@
1
+ from pathlib import Path
2
+
3
+ from arkparse.object_model.ark_game_object import ArkGameObject
4
+ from arkparse.object_model.cluster_data.cluster_data_item import ClusterDataItem
5
+ from arkparse.parsing.ark_archive import ArkArchive
6
+ from arkparse.object_model.cluster_data.cluster_data_dino import ClusterDataDino
7
+
8
+ class ClusterData:
9
+ def __init__(self, path: Path, uuid: str):
10
+ self._path = path
11
+ self._uuid = uuid
12
+ self._archive_object: ArkArchive = self._parse()
13
+ self._ark_data = self._archive_object.get_object_by_class("/Script/ShooterGame.ArkCloudInventoryData")
14
+ if self._ark_data is None:
15
+ self._ark_data = self._archive_object.get_object_by_class("/Script/ShooterGame.PrimalLocalProfile")
16
+ self._ark_data = self._ark_data.get_property_value("MyArkData", None)
17
+ self._ark_data_items: list[ArkGameObject] = self._ark_data.get_property_value("ArkItems", [])
18
+ self._uploaded_dinos: list[ArkGameObject] = self._ark_data.get_property_value("ArkTamedDinosData", [])
19
+
20
+ self.dinos: list[ClusterDataDino] = []
21
+ self.items: list[ClusterDataItem] = []
22
+
23
+ for item in self._ark_data_items:
24
+ item = ClusterDataItem(item, len(self._ark_data_items))
25
+ self.items.append(item)
26
+
27
+ for dino in self._uploaded_dinos:
28
+ dino_data = ClusterDataDino(dino, len(self.dinos))
29
+ self.dinos.append(dino_data)
30
+
31
+ def _check_exists(self):
32
+ path_exists = self._path.exists()
33
+
34
+ if not path_exists:
35
+ raise FileNotFoundError(f"Cluster data folder not found at path: {self._path}")
36
+
37
+ file_path = self._path / f"{self._uuid}"
38
+ file_exists = file_path.exists()
39
+
40
+ if not file_exists:
41
+ raise FileNotFoundError(f"Cluster data file not found in folder: {file_path}")
42
+
43
+ def _parse(self) -> ArkArchive:
44
+ self._check_exists()
45
+
46
+ file_path = self._path / f"{self._uuid}"
47
+ with open(file_path, "rb") as f:
48
+ data = f.read()
49
+
50
+ return ArkArchive(data, from_store=False)
51
+
52
+
@@ -0,0 +1,63 @@
1
+ from arkparse.object_model.dinos.tamed_dino import TamedDino
2
+ from arkparse.parsing.ark_property_container import ArkPropertyContainer
3
+ from arkparse.parsing.ark_archive import ArkArchive
4
+ from arkparse.classes import Dinos
5
+
6
+ class ClusterDataDino:
7
+
8
+ def __init__(self, cluster_dino_data: ArkPropertyContainer, dino_index: int):
9
+ self._data = cluster_dino_data
10
+ self._dino_index = dino_index
11
+ self._actual_dino_data = bytes(cluster_dino_data.get_property_value("DinoData"))
12
+ self._dino_obj = None
13
+ self._status_obj = None
14
+ self._ai_controller_obj = None
15
+ self._inv_obj = None
16
+ self.version = cluster_dino_data.get_property_value("Version")
17
+ self.upload_time = cluster_dino_data.get_property_value("UploadTime")
18
+
19
+ if self.version != 7:
20
+ raise ValueError(f"Unsupported cluster dino data version: {self.version} for dino index {dino_index}")
21
+
22
+ # temp write binary
23
+ self._archive = ArkArchive(self._actual_dino_data, from_store=False, cluster_dino=True)
24
+ for obj in self._archive.objects:
25
+ # print(obj.class_name)
26
+ if obj.class_name in Dinos.all_bps:
27
+ # print(f"Found dino archetype: {obj.class_name}")
28
+ self._dino_obj = obj
29
+ if "CharacterStatusComponent" in obj.class_name:
30
+ # print(f"Found status component: {obj.class_name}")
31
+ self._status_obj = obj
32
+ if "AIController" in obj.class_name:
33
+ # print(f"Found AI controller: {obj.class_name}")
34
+ self._ai_controller_obj = obj
35
+ if "InventoryComponent" in obj.class_name:
36
+ # print(f"Found inventory component: {obj.class_name}")
37
+ self._inv_obj = obj
38
+
39
+ if self._dino_obj is None:
40
+ raise ValueError(f"Could not find dino archetype in cluster dino data for dino index {dino_index}")
41
+
42
+ if self._status_obj is None:
43
+ raise ValueError(f"Could not find status component in cluster dino data for dino index {dino_index}")
44
+
45
+ self.dino = TamedDino.from_object(self._dino_obj, self._status_obj)
46
+ if self._ai_controller_obj:
47
+ self.dino.ai_controller = self._ai_controller_obj
48
+ if self._inv_obj:
49
+ self.dino._inventory = self._inv_obj
50
+ self.dino.inv_uuid = self._inv_obj.uuid
51
+
52
+ # print(self.dino)
53
+
54
+ def __str__(self):
55
+ return f"ClusterDataDino(dino={self.dino})"
56
+
57
+ def to_json_obj(self):
58
+ return {
59
+ "Version": self.version,
60
+ "UploadTime": self.upload_time,
61
+ "Dino": self.dino.to_json_obj()
62
+ }
63
+
@@ -0,0 +1,67 @@
1
+ from enum import Enum
2
+
3
+ from arkparse.object_model.ark_game_object import ArkGameObject
4
+ from arkparse.object_model.misc.inventory_item import InventoryItem
5
+ from arkparse.parsing.ark_property_container import ArkPropertyContainer
6
+ from arkparse.api.equipment_api import EquipmentApi
7
+ from arkparse.api.dino_api import DinoApi
8
+ from arkparse.object_model.cryopods.cryopod import Cryopod
9
+ from arkparse.logging import ArkSaveLogger
10
+
11
+ class ClusterDataItemType(Enum):
12
+ DINO = "Dino"
13
+ EQUIPMENT = "Equipment"
14
+ OTHER = "Other"
15
+
16
+ class ClusterDataItem:
17
+ def __init__(self, cluster_item_data: ArkPropertyContainer, item_index: int):
18
+ self._data = cluster_item_data
19
+ self.version = cluster_item_data.get_property_value("Version")
20
+ self.upload_time = cluster_item_data.get_property_value("UploadTime")
21
+ self.item_type: ClusterDataItemType = None
22
+ self.item: ArkGameObject = None
23
+
24
+ if self.version != 7:
25
+ raise ValueError(f"Unsupported cluster item data version: {self.version} for item index {item_index}")
26
+
27
+ bp = cluster_item_data.get_property_value("ItemArchetype").value.split(' ')[1]
28
+ ArkSaveLogger.objects_log(f"Item found with archetype {bp} and type {self.item_type}. Version: {self.version}. Upload time: {self.upload_time}.")
29
+
30
+ # if "PrimalItem_SCSCryopod" in bp:
31
+ # print(cluster_item_data.to_string())
32
+ # input("Found cryopod item, press enter to continue...")
33
+
34
+ if DinoApi.is_applicable_bp(bp) and (len(cluster_item_data.get_property_value("CustomItemDatas", [])) > 0):
35
+ ArkSaveLogger.objects_log(f"Parsed as dino item with archetype: {bp}")
36
+ self.item_type = ClusterDataItemType.DINO
37
+ obj = ArkGameObject()
38
+ obj.properties = cluster_item_data.properties
39
+ self.item = Cryopod.from_object(obj, blueprint=bp)
40
+ elif EquipmentApi.is_applicable_bp(bp):
41
+ ArkSaveLogger.objects_log(f"Parsed as equipment item with archetype: {bp}")
42
+ self.item_type = ClusterDataItemType.EQUIPMENT
43
+ obj = ArkGameObject()
44
+ obj.properties = cluster_item_data.properties
45
+ self.item = EquipmentApi.bp_to_class(bp).from_object(obj)
46
+ else:
47
+ ArkSaveLogger.objects_log(f"Parsed as other item with archetype: {bp}")
48
+ self.item_type = ClusterDataItemType.OTHER
49
+ obj = ArkGameObject()
50
+ obj.properties = cluster_item_data.properties
51
+ self.item: InventoryItem = InventoryItem.from_object(obj)
52
+ if self.item.quantity == 0:
53
+ self.item.quantity = 1
54
+ self.item.object.blueprint = bp
55
+
56
+ def __str__(self):
57
+ return f"ClusterDataItem(type={self.item_type}, item={self.item})"
58
+
59
+
60
+ def to_json_obj(self):
61
+ return {
62
+ "Version": self.version,
63
+ "UploadTime": self.upload_time,
64
+ "Item": self.item.to_json_obj(),
65
+ "blueprint": self.item.object.blueprint
66
+ }
67
+