arkparser 0.7.1__tar.gz → 0.7.2__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 (63) hide show
  1. {arkparser-0.7.1 → arkparser-0.7.2}/PKG-INFO +1 -1
  2. {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/__init__.py +1 -1
  3. {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/export.py +10 -1
  4. {arkparser-0.7.1 → arkparser-0.7.2}/arkparser.egg-info/PKG-INFO +1 -1
  5. {arkparser-0.7.1 → arkparser-0.7.2}/pyproject.toml +1 -1
  6. {arkparser-0.7.1 → arkparser-0.7.2}/tests/test_cryopod_export.py +76 -0
  7. {arkparser-0.7.1 → arkparser-0.7.2}/LICENSE +0 -0
  8. {arkparser-0.7.1 → arkparser-0.7.2}/README.md +0 -0
  9. {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/common/__init__.py +0 -0
  10. {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/common/binary_reader.py +0 -0
  11. {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/common/exceptions.py +0 -0
  12. {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/common/map_config.py +0 -0
  13. {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/common/normalization.py +0 -0
  14. {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/common/types.py +0 -0
  15. {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/common/version_detection.py +0 -0
  16. {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/data_models.py +0 -0
  17. {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/files/__init__.py +0 -0
  18. {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/files/base.py +0 -0
  19. {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/files/cloud_inventory.py +0 -0
  20. {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/files/profile.py +0 -0
  21. {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/files/tribe.py +0 -0
  22. {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/files/world_save.py +0 -0
  23. {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/game_objects/__init__.py +0 -0
  24. {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/game_objects/container.py +0 -0
  25. {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/game_objects/game_object.py +0 -0
  26. {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/game_objects/location.py +0 -0
  27. {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/properties/__init__.py +0 -0
  28. {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/properties/base.py +0 -0
  29. {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/properties/byte_property.py +0 -0
  30. {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/properties/compound.py +0 -0
  31. {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/properties/primitives.py +0 -0
  32. {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/properties/registry.py +0 -0
  33. {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/structs/__init__.py +0 -0
  34. {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/structs/base.py +0 -0
  35. {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/structs/colors.py +0 -0
  36. {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/structs/misc.py +0 -0
  37. {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/structs/property_list.py +0 -0
  38. {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/structs/registry.py +0 -0
  39. {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/structs/vectors.py +0 -0
  40. {arkparser-0.7.1 → arkparser-0.7.2}/arkparser.egg-info/SOURCES.txt +0 -0
  41. {arkparser-0.7.1 → arkparser-0.7.2}/arkparser.egg-info/dependency_links.txt +0 -0
  42. {arkparser-0.7.1 → arkparser-0.7.2}/arkparser.egg-info/requires.txt +0 -0
  43. {arkparser-0.7.1 → arkparser-0.7.2}/arkparser.egg-info/top_level.txt +0 -0
  44. {arkparser-0.7.1 → arkparser-0.7.2}/setup.cfg +0 -0
  45. {arkparser-0.7.1 → arkparser-0.7.2}/tests/test_asa_header_position.py +0 -0
  46. {arkparser-0.7.1 → arkparser-0.7.2}/tests/test_asa_name_table.py +0 -0
  47. {arkparser-0.7.1 → arkparser-0.7.2}/tests/test_ase_cluster_drift.py +0 -0
  48. {arkparser-0.7.1 → arkparser-0.7.2}/tests/test_binary_reader.py +0 -0
  49. {arkparser-0.7.1 → arkparser-0.7.2}/tests/test_binary_reader_layouts.py +0 -0
  50. {arkparser-0.7.1 → arkparser-0.7.2}/tests/test_cloud_export.py +0 -0
  51. {arkparser-0.7.1 → arkparser-0.7.2}/tests/test_cloud_inventory.py +0 -0
  52. {arkparser-0.7.1 → arkparser-0.7.2}/tests/test_current_stats.py +0 -0
  53. {arkparser-0.7.1 → arkparser-0.7.2}/tests/test_data_models.py +0 -0
  54. {arkparser-0.7.1 → arkparser-0.7.2}/tests/test_export.py +0 -0
  55. {arkparser-0.7.1 → arkparser-0.7.2}/tests/test_game_objects.py +0 -0
  56. {arkparser-0.7.1 → arkparser-0.7.2}/tests/test_golden_exports.py +0 -0
  57. {arkparser-0.7.1 → arkparser-0.7.2}/tests/test_lazy_properties.py +0 -0
  58. {arkparser-0.7.1 → arkparser-0.7.2}/tests/test_profile.py +0 -0
  59. {arkparser-0.7.1 → arkparser-0.7.2}/tests/test_review_fixes.py +0 -0
  60. {arkparser-0.7.1 → arkparser-0.7.2}/tests/test_tribe.py +0 -0
  61. {arkparser-0.7.1 → arkparser-0.7.2}/tests/test_v13_property_layouts.py +0 -0
  62. {arkparser-0.7.1 → arkparser-0.7.2}/tests/test_version_detection.py +0 -0
  63. {arkparser-0.7.1 → arkparser-0.7.2}/tests/test_world_save.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: arkparser
3
- Version: 0.7.1
3
+ Version: 0.7.2
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
@@ -95,4 +95,4 @@ __all__ = [
95
95
  "ArkParseError",
96
96
  ]
97
97
 
98
- __version__ = "0.7.0"
98
+ __version__ = "0.7.2"
@@ -1568,7 +1568,7 @@ def _build_item_owner_lookup(save: t.Any, lookup: dict[t.Any, t.Any]) -> dict[t.
1568
1568
  actor_infos = container._inv_actor_info.items()
1569
1569
  else:
1570
1570
  actor_infos = _iter_inv_actor_info(save)
1571
- for _actor_id, (inv_ref, team_raw, tribe_raw, owner_raw) in actor_infos:
1571
+ for actor_id, (inv_ref, team_raw, tribe_raw, owner_raw) in actor_infos:
1572
1572
  inv = _resolve(inv_ref, lookup)
1573
1573
  if inv is None:
1574
1574
  continue
@@ -1576,9 +1576,11 @@ def _build_item_owner_lookup(save: t.Any, lookup: dict[t.Any, t.Any]) -> dict[t.
1576
1576
  refs = _prop(inv, "InventoryItems")
1577
1577
  if not isinstance(refs, list) or not refs:
1578
1578
  continue
1579
+ owner_obj = lookup.get(actor_id) if actor_id is not None else None
1579
1580
  info = {
1580
1581
  "TargetingTeam": _int(team_raw),
1581
1582
  "TribeName": _str(tribe_raw) or _str(owner_raw),
1583
+ "OwnerLocation": getattr(owner_obj, "location", None),
1582
1584
  }
1583
1585
  for ref in refs:
1584
1586
  item_obj = _resolve(ref, lookup)
@@ -1667,7 +1669,14 @@ def _export_world_cryopods(
1667
1669
  summaries[item_id] = _cryo_summary(cryo)
1668
1670
  owner_info = owner_lookup.get(item_id) if item_id is not None else None
1669
1671
  if owner_info is not None:
1672
+ # Pods stored in inventories carry no actor transform of their
1673
+ # own (always the case on ASA); inherit the owning container's
1674
+ # location so GPS fields don't collapse to 0/0/0.
1675
+ if actor.location is None:
1676
+ actor.location = owner_info.get("OwnerLocation")
1670
1677
  for key, val in owner_info.items():
1678
+ if key == "OwnerLocation":
1679
+ continue
1671
1680
  if val and not cryo.creature_props.get(key):
1672
1681
  cryo.creature_props[key] = val
1673
1682
  record = _tamed_dict(actor, status, empty_lookup, map_config, save, stored=True)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: arkparser
3
- Version: 0.7.1
3
+ Version: 0.7.2
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
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "arkparser"
7
- version = "0.7.1"
7
+ version = "0.7.2"
8
8
  description = "Pure Python parser for ARK: Survival Evolved and ARK: Survival Ascended save files"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -19,7 +19,11 @@ with ``cryo=True``. Two regressions tested here:
19
19
 
20
20
  from __future__ import annotations
21
21
 
22
+ import typing as t
23
+
22
24
  from arkparser.data_models import CryopodCreature
25
+ from arkparser.export import export_tamed
26
+ from arkparser.game_objects.location import LocationData
23
27
 
24
28
 
25
29
  def _asa_blob(current: list[float], max_: list[float]) -> dict[str, object]:
@@ -97,6 +101,78 @@ def test_asa_cryopod_display_name_parses_level_and_species() -> None:
97
101
  assert cryo.species == "Argentavis"
98
102
 
99
103
 
104
+ class FakeObject:
105
+ """Minimal GameObject stand-in for exporter graph tests."""
106
+
107
+ def __init__(
108
+ self,
109
+ obj_id: int,
110
+ class_name: str,
111
+ props: dict[str, t.Any] | None = None,
112
+ location: LocationData | None = None,
113
+ is_item: bool = False,
114
+ ) -> None:
115
+ self.id = obj_id
116
+ self.guid = ""
117
+ self.names: list[str] = []
118
+ self.class_name = class_name
119
+ self.location = location
120
+ self.is_item = is_item
121
+ self.properties: list[t.Any] = []
122
+ self.components: dict[str, t.Any] = {}
123
+ self.props = props or {}
124
+
125
+ def get_property_value(self, name: str, default: t.Any = None, index: int | None = None) -> t.Any:
126
+ key = name if not index else f"{name}_{index}"
127
+ val = self.props.get(key)
128
+ return default if val is None else val
129
+
130
+
131
+ class FakeSave:
132
+ """Save stand-in exposing just what export_tamed needs."""
133
+
134
+ is_asa = True
135
+
136
+ def __init__(self, objects: list[FakeObject], cryos: list[tuple[FakeObject, CryopodCreature]]) -> None:
137
+ self.objects = objects
138
+ self.cryos = cryos
139
+
140
+ def get_tamed_creatures(self) -> list[FakeObject]:
141
+ return []
142
+
143
+ def iter_cryopod_creatures(self) -> t.Iterator[tuple[FakeObject, CryopodCreature]]:
144
+ yield from self.cryos
145
+
146
+
147
+ def test_cryopod_inherits_owning_container_location() -> None:
148
+ """ASA cryopod items live in inventories, not the world: they carry no
149
+ actor transform, so ``item_obj.location`` is None. The exported record
150
+ must fall back to the owning container's (cryofridge / pawn) location
151
+ instead of emitting 0/0/0."""
152
+ fridge = FakeObject(
153
+ 10,
154
+ "CryoFridge_C",
155
+ props={
156
+ "MyInventoryComponent": (None, 11),
157
+ "TargetingTeam": 1500000001,
158
+ "TribeName": "Frisky Dingo",
159
+ },
160
+ location=LocationData(x=10000.0, y=-20000.0, z=300.0),
161
+ )
162
+ inventory = FakeObject(11, "PrimalInventoryBP_C", props={"InventoryItems": [(None, 12)]})
163
+ pod = FakeObject(12, "PrimalItem_WeaponEmptyCryopod_C", is_item=True)
164
+ cryo = CryopodCreature.from_asa_cryopod_data(_asa_blob([0.0] * 11, [0.0] * 11))
165
+ assert cryo is not None
166
+ save = FakeSave([fridge, inventory, pod], [(pod, cryo)])
167
+
168
+ records = export_tamed(save, None)
169
+ assert len(records) == 1
170
+ record = records[0]
171
+ assert record["cryo"] is True
172
+ assert record["tribe"] == "Frisky Dingo"
173
+ assert record["ccc"] == "10000.0 -20000.0 300.0"
174
+
175
+
100
176
  def test_ase_cryopod_keeps_twelve_stat_layout() -> None:
101
177
  """ASE cryopod blobs carry 12 current stats + 12 max stats (25 floats).
102
178
  The ASA fix must not break the ASE path: walking all 12 names is the
File without changes
File without changes
File without changes
File without changes