arkparser 0.4.1__tar.gz → 0.4.3__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 (60) hide show
  1. {arkparser-0.4.1 → arkparser-0.4.3}/PKG-INFO +6 -6
  2. {arkparser-0.4.1 → arkparser-0.4.3}/README.md +5 -5
  3. {arkparser-0.4.1 → arkparser-0.4.3}/arkparser/__init__.py +1 -1
  4. {arkparser-0.4.1 → arkparser-0.4.3}/arkparser/common/binary_reader.py +4 -0
  5. {arkparser-0.4.1 → arkparser-0.4.3}/arkparser/data_models.py +3 -1
  6. {arkparser-0.4.1 → arkparser-0.4.3}/arkparser/export.py +253 -59
  7. {arkparser-0.4.1 → arkparser-0.4.3}/arkparser/files/world_save.py +16 -3
  8. {arkparser-0.4.1 → arkparser-0.4.3}/arkparser/game_objects/game_object.py +23 -2
  9. {arkparser-0.4.1 → arkparser-0.4.3}/arkparser/properties/compound.py +12 -5
  10. {arkparser-0.4.1 → arkparser-0.4.3}/arkparser.egg-info/PKG-INFO +6 -6
  11. {arkparser-0.4.1 → arkparser-0.4.3}/arkparser.egg-info/SOURCES.txt +1 -0
  12. {arkparser-0.4.1 → arkparser-0.4.3}/pyproject.toml +1 -1
  13. arkparser-0.4.3/tests/test_cloud_export.py +98 -0
  14. arkparser-0.4.3/tests/test_review_fixes.py +138 -0
  15. arkparser-0.4.1/tests/test_cloud_export.py +0 -45
  16. {arkparser-0.4.1 → arkparser-0.4.3}/LICENSE +0 -0
  17. {arkparser-0.4.1 → arkparser-0.4.3}/arkparser/common/__init__.py +0 -0
  18. {arkparser-0.4.1 → arkparser-0.4.3}/arkparser/common/exceptions.py +0 -0
  19. {arkparser-0.4.1 → arkparser-0.4.3}/arkparser/common/map_config.py +0 -0
  20. {arkparser-0.4.1 → arkparser-0.4.3}/arkparser/common/normalization.py +0 -0
  21. {arkparser-0.4.1 → arkparser-0.4.3}/arkparser/common/types.py +0 -0
  22. {arkparser-0.4.1 → arkparser-0.4.3}/arkparser/common/version_detection.py +0 -0
  23. {arkparser-0.4.1 → arkparser-0.4.3}/arkparser/files/__init__.py +0 -0
  24. {arkparser-0.4.1 → arkparser-0.4.3}/arkparser/files/base.py +0 -0
  25. {arkparser-0.4.1 → arkparser-0.4.3}/arkparser/files/cloud_inventory.py +0 -0
  26. {arkparser-0.4.1 → arkparser-0.4.3}/arkparser/files/profile.py +0 -0
  27. {arkparser-0.4.1 → arkparser-0.4.3}/arkparser/files/tribe.py +0 -0
  28. {arkparser-0.4.1 → arkparser-0.4.3}/arkparser/game_objects/__init__.py +0 -0
  29. {arkparser-0.4.1 → arkparser-0.4.3}/arkparser/game_objects/container.py +0 -0
  30. {arkparser-0.4.1 → arkparser-0.4.3}/arkparser/game_objects/location.py +0 -0
  31. {arkparser-0.4.1 → arkparser-0.4.3}/arkparser/properties/__init__.py +0 -0
  32. {arkparser-0.4.1 → arkparser-0.4.3}/arkparser/properties/base.py +0 -0
  33. {arkparser-0.4.1 → arkparser-0.4.3}/arkparser/properties/byte_property.py +0 -0
  34. {arkparser-0.4.1 → arkparser-0.4.3}/arkparser/properties/primitives.py +0 -0
  35. {arkparser-0.4.1 → arkparser-0.4.3}/arkparser/properties/registry.py +0 -0
  36. {arkparser-0.4.1 → arkparser-0.4.3}/arkparser/structs/__init__.py +0 -0
  37. {arkparser-0.4.1 → arkparser-0.4.3}/arkparser/structs/base.py +0 -0
  38. {arkparser-0.4.1 → arkparser-0.4.3}/arkparser/structs/colors.py +0 -0
  39. {arkparser-0.4.1 → arkparser-0.4.3}/arkparser/structs/misc.py +0 -0
  40. {arkparser-0.4.1 → arkparser-0.4.3}/arkparser/structs/property_list.py +0 -0
  41. {arkparser-0.4.1 → arkparser-0.4.3}/arkparser/structs/registry.py +0 -0
  42. {arkparser-0.4.1 → arkparser-0.4.3}/arkparser/structs/vectors.py +0 -0
  43. {arkparser-0.4.1 → arkparser-0.4.3}/arkparser.egg-info/dependency_links.txt +0 -0
  44. {arkparser-0.4.1 → arkparser-0.4.3}/arkparser.egg-info/requires.txt +0 -0
  45. {arkparser-0.4.1 → arkparser-0.4.3}/arkparser.egg-info/top_level.txt +0 -0
  46. {arkparser-0.4.1 → arkparser-0.4.3}/setup.cfg +0 -0
  47. {arkparser-0.4.1 → arkparser-0.4.3}/tests/test_asa_header_position.py +0 -0
  48. {arkparser-0.4.1 → arkparser-0.4.3}/tests/test_binary_reader.py +0 -0
  49. {arkparser-0.4.1 → arkparser-0.4.3}/tests/test_binary_reader_layouts.py +0 -0
  50. {arkparser-0.4.1 → arkparser-0.4.3}/tests/test_cloud_inventory.py +0 -0
  51. {arkparser-0.4.1 → arkparser-0.4.3}/tests/test_cryopod_export.py +0 -0
  52. {arkparser-0.4.1 → arkparser-0.4.3}/tests/test_current_stats.py +0 -0
  53. {arkparser-0.4.1 → arkparser-0.4.3}/tests/test_data_models.py +0 -0
  54. {arkparser-0.4.1 → arkparser-0.4.3}/tests/test_export.py +0 -0
  55. {arkparser-0.4.1 → arkparser-0.4.3}/tests/test_game_objects.py +0 -0
  56. {arkparser-0.4.1 → arkparser-0.4.3}/tests/test_profile.py +0 -0
  57. {arkparser-0.4.1 → arkparser-0.4.3}/tests/test_tribe.py +0 -0
  58. {arkparser-0.4.1 → arkparser-0.4.3}/tests/test_v13_property_layouts.py +0 -0
  59. {arkparser-0.4.1 → arkparser-0.4.3}/tests/test_version_detection.py +0 -0
  60. {arkparser-0.4.1 → arkparser-0.4.3}/tests/test_world_save.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: arkparser
3
- Version: 0.4.1
3
+ Version: 0.4.3
4
4
  Summary: Pure Python parser for ARK: Survival Evolved and ARK: Survival Ascended save files
5
5
  Author: Vertyco
6
6
  License-Expression: MIT
@@ -410,11 +410,11 @@ data = export_all(save, map_config, cluster="path/to/cluster")
410
410
  # data["ASV_Tamed"] - now includes cluster cryopod tames (cryo=True)
411
411
  # data["ASV_Players"] - each player's inventory now contains their
412
412
  # uploaded items (entries tagged "uploaded": true),
413
- # matched by cloud-file stem (xuid) ==
414
- # Profile.unique_id.
413
+ # matched by cloud-file stem == the player's
414
+ # .arkprofile filename stem.
415
415
  ```
416
416
 
417
- Cluster items are spliced into the owning player's `inventory`; no separate `ASV_ClusterItems` file is emitted. The match works because every cluster file is named after the owning player's Steam id / platform UUID, which is the same value as `Profile.unique_id`.
417
+ Cluster items are spliced into the owning player's `inventory`; no separate `ASV_ClusterItems` file is emitted. The match works because every cluster file and the player's `.arkprofile` share a stem — the Steam id on ASE, the hex platform UUID on ASA — so the join is keyed on the profile's source filename stem. (`Profile.unique_id` equals that stem only on ASE; on ASA it is the numeric net id, not the UUID filename, so loading profiles from real file paths — which sets `Profile.source_path` — is required for the ASA splice.)
418
418
 
419
419
  Pre-loaded `CloudInventory` instances also work (`cluster=[inv1, inv2, ...]`).
420
420
 
@@ -436,7 +436,7 @@ data = export_cloud_inventory(cloud)
436
436
  # }
437
437
  ```
438
438
 
439
- Each `ASV_Items` entry carries `itemId`, `qty`, `blueprint`, `id` (combined ItemID1_ItemID2), `upload_time` (ISO 8601 with UTC offset), and item-class-specific stats (`durability_max`, `damage`, `armor`, `hypo`, `hyper`, `crafter`, `crafter_tribe`, `skill_bonus`, `loaded_ammo`, `quality`, `rating`, `c0`..`c5` paint regions, `drop_location`, `egg_*` for fertilized eggs, `dino_*` for cryopod items, etc). Default / unset fields are filtered, NaN floats dropped, `"Unknown"` crafter strings nulled.
439
+ Each `ASV_Items` entry carries `itemId`, `qty`, `blueprint`, `id` (combined ItemID1_ItemID2), `uploadedTime` (ISO 8601 with UTC offset), and item-class-specific stats (`durability_max`, `damage`, `armor`, `hypo`, `hyper`, `crafter`, `crafter_tribe`, `skill_bonus`, `loaded_ammo`, `quality`, `rating`, `c0`..`c5` paint regions, `drop_location`, `egg_*` for fertilized eggs, `dino_*` for cryopod items, etc). Default / unset fields are filtered, NaN floats dropped, `"Unknown"` crafter strings nulled.
440
440
 
441
441
  The low-level helpers are also available:
442
442
  - `export_cluster_uploads(cluster_invs, map_config=None) -> list[dict]` — tamed-shape records (incl. cryopod-as-item dinos) across the supplied cloud files
@@ -589,7 +589,7 @@ All four expose `from_*` constructors and `to_dict()` for serialization.
589
589
  |---|---|---|
590
590
  | `export_tamed(save, map_config=None)` | `list[dict]` | `ASV_Tamed` records |
591
591
  | `export_wild(save, map_config=None)` | `list[dict]` | `ASV_Wild` records |
592
- | `export_players(save, map_config=None, cluster_inventories=None)` | `list[dict]` | `ASV_Players` records (from Profile parsers). Pass `cluster_inventories` to splice each player's uploaded items into their `inventory` (entries tagged `uploaded: true`, matched by xuid stem == `Profile.unique_id`) |
592
+ | `export_players(save, map_config=None, cluster_inventories=None)` | `list[dict]` | `ASV_Players` records (from Profile parsers). Pass `cluster_inventories` to splice each player's uploaded items into their `inventory` (entries tagged `uploaded: true`, matched by cloud-file stem == the player's `.arkprofile` filename stem) |
593
593
  | `export_tribes(save)` | `list[dict]` | `ASV_Tribes` records |
594
594
  | `export_structures(save, map_config=None)` | `list[dict]` | `ASV_Structures` records |
595
595
  | `export_tribe_logs(save)` | `list[dict]` | `ASV_TribeLogs` records |
@@ -376,11 +376,11 @@ data = export_all(save, map_config, cluster="path/to/cluster")
376
376
  # data["ASV_Tamed"] - now includes cluster cryopod tames (cryo=True)
377
377
  # data["ASV_Players"] - each player's inventory now contains their
378
378
  # uploaded items (entries tagged "uploaded": true),
379
- # matched by cloud-file stem (xuid) ==
380
- # Profile.unique_id.
379
+ # matched by cloud-file stem == the player's
380
+ # .arkprofile filename stem.
381
381
  ```
382
382
 
383
- Cluster items are spliced into the owning player's `inventory`; no separate `ASV_ClusterItems` file is emitted. The match works because every cluster file is named after the owning player's Steam id / platform UUID, which is the same value as `Profile.unique_id`.
383
+ Cluster items are spliced into the owning player's `inventory`; no separate `ASV_ClusterItems` file is emitted. The match works because every cluster file and the player's `.arkprofile` share a stem — the Steam id on ASE, the hex platform UUID on ASA — so the join is keyed on the profile's source filename stem. (`Profile.unique_id` equals that stem only on ASE; on ASA it is the numeric net id, not the UUID filename, so loading profiles from real file paths — which sets `Profile.source_path` — is required for the ASA splice.)
384
384
 
385
385
  Pre-loaded `CloudInventory` instances also work (`cluster=[inv1, inv2, ...]`).
386
386
 
@@ -402,7 +402,7 @@ data = export_cloud_inventory(cloud)
402
402
  # }
403
403
  ```
404
404
 
405
- Each `ASV_Items` entry carries `itemId`, `qty`, `blueprint`, `id` (combined ItemID1_ItemID2), `upload_time` (ISO 8601 with UTC offset), and item-class-specific stats (`durability_max`, `damage`, `armor`, `hypo`, `hyper`, `crafter`, `crafter_tribe`, `skill_bonus`, `loaded_ammo`, `quality`, `rating`, `c0`..`c5` paint regions, `drop_location`, `egg_*` for fertilized eggs, `dino_*` for cryopod items, etc). Default / unset fields are filtered, NaN floats dropped, `"Unknown"` crafter strings nulled.
405
+ Each `ASV_Items` entry carries `itemId`, `qty`, `blueprint`, `id` (combined ItemID1_ItemID2), `uploadedTime` (ISO 8601 with UTC offset), and item-class-specific stats (`durability_max`, `damage`, `armor`, `hypo`, `hyper`, `crafter`, `crafter_tribe`, `skill_bonus`, `loaded_ammo`, `quality`, `rating`, `c0`..`c5` paint regions, `drop_location`, `egg_*` for fertilized eggs, `dino_*` for cryopod items, etc). Default / unset fields are filtered, NaN floats dropped, `"Unknown"` crafter strings nulled.
406
406
 
407
407
  The low-level helpers are also available:
408
408
  - `export_cluster_uploads(cluster_invs, map_config=None) -> list[dict]` — tamed-shape records (incl. cryopod-as-item dinos) across the supplied cloud files
@@ -555,7 +555,7 @@ All four expose `from_*` constructors and `to_dict()` for serialization.
555
555
  |---|---|---|
556
556
  | `export_tamed(save, map_config=None)` | `list[dict]` | `ASV_Tamed` records |
557
557
  | `export_wild(save, map_config=None)` | `list[dict]` | `ASV_Wild` records |
558
- | `export_players(save, map_config=None, cluster_inventories=None)` | `list[dict]` | `ASV_Players` records (from Profile parsers). Pass `cluster_inventories` to splice each player's uploaded items into their `inventory` (entries tagged `uploaded: true`, matched by xuid stem == `Profile.unique_id`) |
558
+ | `export_players(save, map_config=None, cluster_inventories=None)` | `list[dict]` | `ASV_Players` records (from Profile parsers). Pass `cluster_inventories` to splice each player's uploaded items into their `inventory` (entries tagged `uploaded: true`, matched by cloud-file stem == the player's `.arkprofile` filename stem) |
559
559
  | `export_tribes(save)` | `list[dict]` | `ASV_Tribes` records |
560
560
  | `export_structures(save, map_config=None)` | `list[dict]` | `ASV_Structures` records |
561
561
  | `export_tribe_logs(save)` | `list[dict]` | `ASV_TribeLogs` records |
@@ -95,4 +95,4 @@ __all__ = [
95
95
  "ArkParseError",
96
96
  ]
97
97
 
98
- __version__ = "0.4.0"
98
+ __version__ = "0.4.3"
@@ -242,9 +242,13 @@ class BinaryReader:
242
242
  if length == 0:
243
243
  return ""
244
244
  if length == 1:
245
+ if self._pos + 1 > self._size:
246
+ raise EndOfDataError(1, self._size - self._pos)
245
247
  self._pos += 1 # single null byte
246
248
  return ""
247
249
  if length == -1:
250
+ if self._pos + 2 > self._size:
251
+ raise EndOfDataError(2, self._size - self._pos)
248
252
  self._pos += 2 # UTF-16 null
249
253
  return ""
250
254
  if length < 0:
@@ -472,7 +472,9 @@ class CryopodCreature:
472
472
  Both ASA and ASE store cryopod creature data using:
473
473
  - CustomDataStrings: [class_name, display_name, colors_str, ?, gender, ?, ?, ...]
474
474
  - ASE has 7 strings, ASA has 10+ strings (with species at index 9)
475
- - CustomDataFloats: [current_stats x 12, max_stats x 12, ...]
475
+ - CustomDataFloats: ASE = [current x 12, max x 12, +1] (25); ASA = [current
476
+ x 11 (no CraftingSkill), max x 11, extras] (36). See the per-format
477
+ branch below — the layouts genuinely differ in current-stat width.
476
478
  - CustomDataNames: Color names for the 6 color regions
477
479
 
478
480
  Args: