arkparser 0.1.0__py3-none-any.whl
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.
- arkparser/__init__.py +117 -0
- arkparser/common/__init__.py +72 -0
- arkparser/common/binary_reader.py +402 -0
- arkparser/common/exceptions.py +99 -0
- arkparser/common/map_config.py +166 -0
- arkparser/common/types.py +249 -0
- arkparser/common/version_detection.py +195 -0
- arkparser/data_models.py +801 -0
- arkparser/export.py +485 -0
- arkparser/files/__init__.py +25 -0
- arkparser/files/base.py +309 -0
- arkparser/files/cloud_inventory.py +259 -0
- arkparser/files/profile.py +205 -0
- arkparser/files/tribe.py +155 -0
- arkparser/files/world_save.py +699 -0
- arkparser/game_objects/__init__.py +32 -0
- arkparser/game_objects/container.py +180 -0
- arkparser/game_objects/game_object.py +273 -0
- arkparser/game_objects/location.py +87 -0
- arkparser/models/__init__.py +29 -0
- arkparser/models/character.py +227 -0
- arkparser/models/creature.py +642 -0
- arkparser/models/item.py +207 -0
- arkparser/models/player.py +263 -0
- arkparser/models/stats.py +226 -0
- arkparser/models/structure.py +176 -0
- arkparser/models/tribe.py +291 -0
- arkparser/properties/__init__.py +77 -0
- arkparser/properties/base.py +329 -0
- arkparser/properties/byte_property.py +230 -0
- arkparser/properties/compound.py +1125 -0
- arkparser/properties/primitives.py +803 -0
- arkparser/properties/registry.py +236 -0
- arkparser/py.typed +0 -0
- arkparser/structs/__init__.py +60 -0
- arkparser/structs/base.py +63 -0
- arkparser/structs/colors.py +108 -0
- arkparser/structs/misc.py +133 -0
- arkparser/structs/property_list.py +101 -0
- arkparser/structs/registry.py +140 -0
- arkparser/structs/vectors.py +221 -0
- arkparser-0.1.0.dist-info/METADATA +833 -0
- arkparser-0.1.0.dist-info/RECORD +46 -0
- arkparser-0.1.0.dist-info/WHEEL +5 -0
- arkparser-0.1.0.dist-info/licenses/LICENSE +21 -0
- arkparser-0.1.0.dist-info/top_level.txt +1 -0
arkparser/export.py
ADDED
|
@@ -0,0 +1,485 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Export functions for producing C#-compatible JSON outputs.
|
|
3
|
+
|
|
4
|
+
Generates the 7 ASV export formats from parsed save data:
|
|
5
|
+
- ASV_Tamed: Tamed creature list
|
|
6
|
+
- ASV_Wild: Wild creature list
|
|
7
|
+
- ASV_Players: Player profiles
|
|
8
|
+
- ASV_Tribes: Tribe data
|
|
9
|
+
- ASV_Structures: Placed structures
|
|
10
|
+
- ASV_TribeLogs: Tribe log entries
|
|
11
|
+
- ASV_MapStructures: All structures with map coordinates
|
|
12
|
+
|
|
13
|
+
Each function accepts a parsed savegame (ASE or ASA) plus optional
|
|
14
|
+
map config and returns a list of dictionaries ready for JSON serialization.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
import json
|
|
20
|
+
import typing as t
|
|
21
|
+
from pathlib import Path
|
|
22
|
+
|
|
23
|
+
from arkparser.common.map_config import MapConfig, get_map_config
|
|
24
|
+
from arkparser.models.creature import TamedCreature, WildCreature
|
|
25
|
+
from arkparser.models.player import Player
|
|
26
|
+
from arkparser.models.stats import Location
|
|
27
|
+
from arkparser.models.structure import Structure
|
|
28
|
+
from arkparser.models.tribe import Tribe as TribeModel
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def _apply_map(loc: Location | None, map_config: MapConfig | None) -> Location | None:
|
|
32
|
+
"""Attach map config to a location for GPS conversion."""
|
|
33
|
+
if loc and map_config:
|
|
34
|
+
return loc.with_map(map_config)
|
|
35
|
+
return loc
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
# -------------------------------------------------------------------------
|
|
39
|
+
# Tamed Creatures (ASV_Tamed)
|
|
40
|
+
# -------------------------------------------------------------------------
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def export_tamed(
|
|
44
|
+
save: t.Any,
|
|
45
|
+
map_config: MapConfig | None = None,
|
|
46
|
+
) -> list[dict[str, t.Any]]:
|
|
47
|
+
"""
|
|
48
|
+
Export tamed creatures in ASV_Tamed format.
|
|
49
|
+
|
|
50
|
+
Args:
|
|
51
|
+
save: A parsed savegame (WorldSave — auto-detects ASE/ASA).
|
|
52
|
+
map_config: Optional map config for GPS coordinates.
|
|
53
|
+
|
|
54
|
+
Returns:
|
|
55
|
+
List of tamed creature dictionaries.
|
|
56
|
+
"""
|
|
57
|
+
results: list[dict[str, t.Any]] = []
|
|
58
|
+
|
|
59
|
+
tamed_objs = save.tamed_objects if hasattr(save, "tamed_objects") else []
|
|
60
|
+
objects = save.objects if hasattr(save, "objects") else {}
|
|
61
|
+
obj_lookup = _build_lookup(objects)
|
|
62
|
+
|
|
63
|
+
for obj in tamed_objs:
|
|
64
|
+
status = _find_status_component(obj, obj_lookup)
|
|
65
|
+
creature = TamedCreature.from_game_object(obj, status)
|
|
66
|
+
data = creature.to_dict()
|
|
67
|
+
|
|
68
|
+
if creature.location and map_config:
|
|
69
|
+
mapped_loc = creature.location.with_map(map_config)
|
|
70
|
+
if mapped_loc.latitude is not None:
|
|
71
|
+
data["lat"] = mapped_loc.latitude
|
|
72
|
+
if mapped_loc.longitude is not None:
|
|
73
|
+
data["lon"] = mapped_loc.longitude
|
|
74
|
+
|
|
75
|
+
inventory = _get_inventory_items(obj, obj_lookup)
|
|
76
|
+
data["inventory"] = inventory
|
|
77
|
+
|
|
78
|
+
results.append(data)
|
|
79
|
+
|
|
80
|
+
return results
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
# -------------------------------------------------------------------------
|
|
84
|
+
# Wild Creatures (ASV_Wild)
|
|
85
|
+
# -------------------------------------------------------------------------
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def export_wild(
|
|
89
|
+
save: t.Any,
|
|
90
|
+
map_config: MapConfig | None = None,
|
|
91
|
+
) -> list[dict[str, t.Any]]:
|
|
92
|
+
"""
|
|
93
|
+
Export wild creatures in ASV_Wild format.
|
|
94
|
+
|
|
95
|
+
Args:
|
|
96
|
+
save: A parsed savegame.
|
|
97
|
+
map_config: Optional map config for GPS coordinates.
|
|
98
|
+
|
|
99
|
+
Returns:
|
|
100
|
+
List of wild creature dictionaries.
|
|
101
|
+
"""
|
|
102
|
+
results: list[dict[str, t.Any]] = []
|
|
103
|
+
|
|
104
|
+
wild_objs = save.wild_objects if hasattr(save, "wild_objects") else []
|
|
105
|
+
objects = save.objects if hasattr(save, "objects") else {}
|
|
106
|
+
obj_lookup = _build_lookup(objects)
|
|
107
|
+
|
|
108
|
+
for obj in wild_objs:
|
|
109
|
+
status = _find_status_component(obj, obj_lookup)
|
|
110
|
+
creature = WildCreature.from_game_object(obj, status)
|
|
111
|
+
data = creature.to_dict()
|
|
112
|
+
|
|
113
|
+
if creature.location and map_config:
|
|
114
|
+
mapped_loc = creature.location.with_map(map_config)
|
|
115
|
+
if mapped_loc.latitude is not None:
|
|
116
|
+
data["lat"] = mapped_loc.latitude
|
|
117
|
+
if mapped_loc.longitude is not None:
|
|
118
|
+
data["lon"] = mapped_loc.longitude
|
|
119
|
+
|
|
120
|
+
results.append(data)
|
|
121
|
+
|
|
122
|
+
return results
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
# -------------------------------------------------------------------------
|
|
126
|
+
# Players (ASV_Players)
|
|
127
|
+
# -------------------------------------------------------------------------
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def export_players(
|
|
131
|
+
save: t.Any,
|
|
132
|
+
map_config: MapConfig | None = None,
|
|
133
|
+
) -> list[dict[str, t.Any]]:
|
|
134
|
+
"""
|
|
135
|
+
Export player profiles in ASV_Players format.
|
|
136
|
+
|
|
137
|
+
Args:
|
|
138
|
+
save: A parsed savegame with profile data.
|
|
139
|
+
map_config: Optional map config for GPS coordinates.
|
|
140
|
+
|
|
141
|
+
Returns:
|
|
142
|
+
List of player dictionaries.
|
|
143
|
+
"""
|
|
144
|
+
results: list[dict[str, t.Any]] = []
|
|
145
|
+
|
|
146
|
+
profiles = save.profiles if hasattr(save, "profiles") else []
|
|
147
|
+
|
|
148
|
+
for profile in profiles:
|
|
149
|
+
profile_obj = None
|
|
150
|
+
status_obj = None
|
|
151
|
+
|
|
152
|
+
if hasattr(profile, "profile"):
|
|
153
|
+
profile_obj = profile.profile
|
|
154
|
+
elif hasattr(profile, "objects") and profile.objects:
|
|
155
|
+
profile_obj = profile.objects[0]
|
|
156
|
+
|
|
157
|
+
if hasattr(profile, "objects"):
|
|
158
|
+
for obj in profile.objects:
|
|
159
|
+
cs = str(getattr(obj, "class_name", ""))
|
|
160
|
+
if "StatusComponent" in cs or "CharacterStatus" in cs:
|
|
161
|
+
status_obj = obj
|
|
162
|
+
break
|
|
163
|
+
|
|
164
|
+
if profile_obj is None:
|
|
165
|
+
continue
|
|
166
|
+
|
|
167
|
+
player = Player.from_game_object(profile_obj, status_obj)
|
|
168
|
+
data = player.to_dict()
|
|
169
|
+
results.append(data)
|
|
170
|
+
|
|
171
|
+
return results
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
# -------------------------------------------------------------------------
|
|
175
|
+
# Tribes (ASV_Tribes)
|
|
176
|
+
# -------------------------------------------------------------------------
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
def export_tribes(
|
|
180
|
+
save: t.Any,
|
|
181
|
+
) -> list[dict[str, t.Any]]:
|
|
182
|
+
"""
|
|
183
|
+
Export tribe data in ASV_Tribes format.
|
|
184
|
+
|
|
185
|
+
Args:
|
|
186
|
+
save: A parsed savegame with tribe data.
|
|
187
|
+
|
|
188
|
+
Returns:
|
|
189
|
+
List of tribe dictionaries.
|
|
190
|
+
"""
|
|
191
|
+
results: list[dict[str, t.Any]] = []
|
|
192
|
+
|
|
193
|
+
tribes = save.tribes if hasattr(save, "tribes") else []
|
|
194
|
+
|
|
195
|
+
for tribe_parser in tribes:
|
|
196
|
+
tribe_obj = None
|
|
197
|
+
if hasattr(tribe_parser, "tribe"):
|
|
198
|
+
tribe_obj = tribe_parser.tribe
|
|
199
|
+
elif hasattr(tribe_parser, "objects") and tribe_parser.objects:
|
|
200
|
+
tribe_obj = tribe_parser.objects[0]
|
|
201
|
+
|
|
202
|
+
if tribe_obj is None:
|
|
203
|
+
continue
|
|
204
|
+
|
|
205
|
+
tribe_model = TribeModel.from_game_object(tribe_obj)
|
|
206
|
+
data = tribe_model.to_dict()
|
|
207
|
+
results.append(data)
|
|
208
|
+
|
|
209
|
+
return results
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
# -------------------------------------------------------------------------
|
|
213
|
+
# Structures (ASV_Structures)
|
|
214
|
+
# -------------------------------------------------------------------------
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
def export_structures(
|
|
218
|
+
save: t.Any,
|
|
219
|
+
map_config: MapConfig | None = None,
|
|
220
|
+
) -> list[dict[str, t.Any]]:
|
|
221
|
+
"""
|
|
222
|
+
Export placed structures in ASV_Structures format.
|
|
223
|
+
|
|
224
|
+
Args:
|
|
225
|
+
save: A parsed savegame.
|
|
226
|
+
map_config: Optional map config for GPS coordinates.
|
|
227
|
+
|
|
228
|
+
Returns:
|
|
229
|
+
List of structure dictionaries.
|
|
230
|
+
"""
|
|
231
|
+
results: list[dict[str, t.Any]] = []
|
|
232
|
+
|
|
233
|
+
struct_objs = save.structure_objects if hasattr(save, "structure_objects") else []
|
|
234
|
+
|
|
235
|
+
for obj in struct_objs:
|
|
236
|
+
structure = Structure.from_game_object(obj)
|
|
237
|
+
data = structure.to_dict()
|
|
238
|
+
|
|
239
|
+
if structure.location and map_config:
|
|
240
|
+
mapped_loc = structure.location.with_map(map_config)
|
|
241
|
+
if mapped_loc.latitude is not None:
|
|
242
|
+
data["lat"] = mapped_loc.latitude
|
|
243
|
+
if mapped_loc.longitude is not None:
|
|
244
|
+
data["lon"] = mapped_loc.longitude
|
|
245
|
+
|
|
246
|
+
results.append(data)
|
|
247
|
+
|
|
248
|
+
return results
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
# -------------------------------------------------------------------------
|
|
252
|
+
# Tribe Logs (ASV_TribeLogs)
|
|
253
|
+
# -------------------------------------------------------------------------
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
def export_tribe_logs(
|
|
257
|
+
save: t.Any,
|
|
258
|
+
) -> list[dict[str, t.Any]]:
|
|
259
|
+
"""
|
|
260
|
+
Export tribe log entries in ASV_TribeLogs format.
|
|
261
|
+
|
|
262
|
+
Args:
|
|
263
|
+
save: A parsed savegame with tribe data.
|
|
264
|
+
|
|
265
|
+
Returns:
|
|
266
|
+
List of tribe log dictionaries (one per tribe).
|
|
267
|
+
"""
|
|
268
|
+
results: list[dict[str, t.Any]] = []
|
|
269
|
+
|
|
270
|
+
tribes = save.tribes if hasattr(save, "tribes") else []
|
|
271
|
+
|
|
272
|
+
for tribe_parser in tribes:
|
|
273
|
+
tribe_obj = None
|
|
274
|
+
if hasattr(tribe_parser, "tribe"):
|
|
275
|
+
tribe_obj = tribe_parser.tribe
|
|
276
|
+
elif hasattr(tribe_parser, "objects") and tribe_parser.objects:
|
|
277
|
+
tribe_obj = tribe_parser.objects[0]
|
|
278
|
+
|
|
279
|
+
if tribe_obj is None:
|
|
280
|
+
continue
|
|
281
|
+
|
|
282
|
+
tribe_model = TribeModel.from_game_object(tribe_obj)
|
|
283
|
+
results.append(
|
|
284
|
+
{
|
|
285
|
+
"tribeid": tribe_model.tribe_id,
|
|
286
|
+
"tribe": tribe_model.name,
|
|
287
|
+
"logs": [entry.to_dict() for entry in tribe_model.log],
|
|
288
|
+
}
|
|
289
|
+
)
|
|
290
|
+
|
|
291
|
+
return results
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
# -------------------------------------------------------------------------
|
|
295
|
+
# Map Structures (ASV_MapStructures) — structures with GPS coords
|
|
296
|
+
# -------------------------------------------------------------------------
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
def export_map_structures(
|
|
300
|
+
save: t.Any,
|
|
301
|
+
map_config: MapConfig | None = None,
|
|
302
|
+
) -> list[dict[str, t.Any]]:
|
|
303
|
+
"""
|
|
304
|
+
Export structures with map coordinates in ASV_MapStructures format.
|
|
305
|
+
|
|
306
|
+
Same as ASV_Structures but intended for map visualisation with GPS coords.
|
|
307
|
+
|
|
308
|
+
Args:
|
|
309
|
+
save: A parsed savegame.
|
|
310
|
+
map_config: Map config for GPS coordinate conversion.
|
|
311
|
+
|
|
312
|
+
Returns:
|
|
313
|
+
List of structure dictionaries with GPS coordinates.
|
|
314
|
+
"""
|
|
315
|
+
return export_structures(save, map_config)
|
|
316
|
+
|
|
317
|
+
|
|
318
|
+
# -------------------------------------------------------------------------
|
|
319
|
+
# Full Export — all 7 formats at once
|
|
320
|
+
# -------------------------------------------------------------------------
|
|
321
|
+
|
|
322
|
+
|
|
323
|
+
def export_all(
|
|
324
|
+
save: t.Any,
|
|
325
|
+
map_config: MapConfig | None = None,
|
|
326
|
+
) -> dict[str, list[dict[str, t.Any]]]:
|
|
327
|
+
"""
|
|
328
|
+
Export all 7 ASV formats at once.
|
|
329
|
+
|
|
330
|
+
Args:
|
|
331
|
+
save: A parsed savegame.
|
|
332
|
+
map_config: Optional map config for GPS coordinates.
|
|
333
|
+
|
|
334
|
+
Returns:
|
|
335
|
+
Dictionary with keys ASV_Tamed, ASV_Wild, ASV_Players,
|
|
336
|
+
ASV_Tribes, ASV_Structures, ASV_TribeLogs, ASV_MapStructures.
|
|
337
|
+
"""
|
|
338
|
+
return {
|
|
339
|
+
"ASV_Tamed": export_tamed(save, map_config),
|
|
340
|
+
"ASV_Wild": export_wild(save, map_config),
|
|
341
|
+
"ASV_Players": export_players(save, map_config),
|
|
342
|
+
"ASV_Tribes": export_tribes(save),
|
|
343
|
+
"ASV_Structures": export_structures(save, map_config),
|
|
344
|
+
"ASV_TribeLogs": export_tribe_logs(save),
|
|
345
|
+
"ASV_MapStructures": export_map_structures(save, map_config),
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
|
|
349
|
+
def export_to_files(
|
|
350
|
+
save: t.Any,
|
|
351
|
+
output_dir: str | Path,
|
|
352
|
+
map_config: MapConfig | None = None,
|
|
353
|
+
) -> list[Path]:
|
|
354
|
+
"""
|
|
355
|
+
Export all 7 ASV formats to JSON files.
|
|
356
|
+
|
|
357
|
+
Args:
|
|
358
|
+
save: A parsed savegame.
|
|
359
|
+
output_dir: Directory to write JSON files to.
|
|
360
|
+
map_config: Optional map config for GPS coordinates.
|
|
361
|
+
|
|
362
|
+
Returns:
|
|
363
|
+
List of paths to the created files.
|
|
364
|
+
"""
|
|
365
|
+
out = Path(output_dir)
|
|
366
|
+
out.mkdir(parents=True, exist_ok=True)
|
|
367
|
+
|
|
368
|
+
all_data = export_all(save, map_config)
|
|
369
|
+
created: list[Path] = []
|
|
370
|
+
|
|
371
|
+
for name, data in all_data.items():
|
|
372
|
+
path = out / f"{name}.json"
|
|
373
|
+
path.write_text(json.dumps(data, indent=2, default=str), encoding="utf-8")
|
|
374
|
+
created.append(path)
|
|
375
|
+
|
|
376
|
+
return created
|
|
377
|
+
|
|
378
|
+
|
|
379
|
+
# -------------------------------------------------------------------------
|
|
380
|
+
# Helpers
|
|
381
|
+
# -------------------------------------------------------------------------
|
|
382
|
+
|
|
383
|
+
|
|
384
|
+
def _build_lookup(objects: t.Any) -> dict[t.Any, t.Any]:
|
|
385
|
+
"""Build an object lookup dict from various container formats."""
|
|
386
|
+
if isinstance(objects, dict):
|
|
387
|
+
return objects
|
|
388
|
+
if isinstance(objects, list):
|
|
389
|
+
result: dict[t.Any, t.Any] = {}
|
|
390
|
+
for obj in objects:
|
|
391
|
+
key = getattr(obj, "guid", None) or id(obj)
|
|
392
|
+
result[key] = obj
|
|
393
|
+
return result
|
|
394
|
+
return {}
|
|
395
|
+
|
|
396
|
+
|
|
397
|
+
def _find_status_component(obj: t.Any, lookup: dict[t.Any, t.Any]) -> t.Any:
|
|
398
|
+
"""
|
|
399
|
+
Find the status component object for a creature.
|
|
400
|
+
|
|
401
|
+
Looks for MyCharacterStatusComponent reference or component link.
|
|
402
|
+
"""
|
|
403
|
+
# Check components dict
|
|
404
|
+
if hasattr(obj, "components"):
|
|
405
|
+
for key, comp in obj.components.items():
|
|
406
|
+
if "status" in str(key).lower():
|
|
407
|
+
return comp
|
|
408
|
+
|
|
409
|
+
# Check property reference
|
|
410
|
+
ref = None
|
|
411
|
+
if hasattr(obj, "get_property_value"):
|
|
412
|
+
ref = obj.get_property_value("MyCharacterStatusComponent", default=None)
|
|
413
|
+
|
|
414
|
+
if ref is None:
|
|
415
|
+
return None
|
|
416
|
+
|
|
417
|
+
# Resolve reference
|
|
418
|
+
guid = None
|
|
419
|
+
if hasattr(ref, "guid") and ref.guid:
|
|
420
|
+
guid = ref.guid
|
|
421
|
+
elif hasattr(ref, "object_id") and ref.object_id >= 0:
|
|
422
|
+
if isinstance(lookup, list):
|
|
423
|
+
return lookup[ref.object_id] if ref.object_id < len(lookup) else None
|
|
424
|
+
|
|
425
|
+
if guid and guid in lookup:
|
|
426
|
+
return lookup[guid]
|
|
427
|
+
|
|
428
|
+
return None
|
|
429
|
+
|
|
430
|
+
|
|
431
|
+
def _get_inventory_items(obj: t.Any, lookup: dict[t.Any, t.Any]) -> list[dict[str, t.Any]]:
|
|
432
|
+
"""Get inventory items for a creature."""
|
|
433
|
+
items: list[dict[str, t.Any]] = []
|
|
434
|
+
|
|
435
|
+
inv_ref = None
|
|
436
|
+
if hasattr(obj, "get_property_value"):
|
|
437
|
+
inv_ref = obj.get_property_value("MyInventoryComponent", default=None)
|
|
438
|
+
|
|
439
|
+
if inv_ref is None:
|
|
440
|
+
return items
|
|
441
|
+
|
|
442
|
+
# Resolve inventory object
|
|
443
|
+
inv_obj = None
|
|
444
|
+
guid = None
|
|
445
|
+
if hasattr(inv_ref, "guid") and inv_ref.guid:
|
|
446
|
+
guid = inv_ref.guid
|
|
447
|
+
|
|
448
|
+
if guid and guid in lookup:
|
|
449
|
+
inv_obj = lookup[guid]
|
|
450
|
+
|
|
451
|
+
if inv_obj is None:
|
|
452
|
+
return items
|
|
453
|
+
|
|
454
|
+
# Get item references from inventory
|
|
455
|
+
item_refs = None
|
|
456
|
+
if hasattr(inv_obj, "get_property_value"):
|
|
457
|
+
item_refs = inv_obj.get_property_value("InventoryItems", default=None)
|
|
458
|
+
|
|
459
|
+
if not isinstance(item_refs, list):
|
|
460
|
+
return items
|
|
461
|
+
|
|
462
|
+
for ref in item_refs:
|
|
463
|
+
item_guid = None
|
|
464
|
+
if hasattr(ref, "guid") and ref.guid:
|
|
465
|
+
item_guid = ref.guid
|
|
466
|
+
|
|
467
|
+
if item_guid and item_guid in lookup:
|
|
468
|
+
item_obj = lookup[item_guid]
|
|
469
|
+
item_class = str(getattr(item_obj, "class_name", ""))
|
|
470
|
+
qty = 1
|
|
471
|
+
is_bp = False
|
|
472
|
+
if hasattr(item_obj, "get_property_value"):
|
|
473
|
+
q = item_obj.get_property_value("ItemQuantity", default=1)
|
|
474
|
+
qty = int(q) if q else 1
|
|
475
|
+
is_bp = item_obj.get_property_value("bIsBlueprint", default=False)
|
|
476
|
+
|
|
477
|
+
items.append(
|
|
478
|
+
{
|
|
479
|
+
"itemId": item_class,
|
|
480
|
+
"qty": qty,
|
|
481
|
+
"blueprint": bool(is_bp),
|
|
482
|
+
}
|
|
483
|
+
)
|
|
484
|
+
|
|
485
|
+
return items
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"""
|
|
2
|
+
File parsers for ARK save data.
|
|
3
|
+
|
|
4
|
+
This module provides parsers for various ARK save file formats:
|
|
5
|
+
- Profile: Player profile data (.arkprofile)
|
|
6
|
+
- Tribe: Tribe data (.arktribe)
|
|
7
|
+
- CloudInventory: Obelisk/cloud inventory data (no extension)
|
|
8
|
+
- WorldSave: World save data (.ark) — auto-detects ASE binary and ASA SQLite
|
|
9
|
+
|
|
10
|
+
All parsers support both ASE and ASA formats with automatic detection.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from .base import ArkFile
|
|
14
|
+
from .cloud_inventory import CloudInventory
|
|
15
|
+
from .profile import Profile
|
|
16
|
+
from .tribe import Tribe
|
|
17
|
+
from .world_save import WorldSave
|
|
18
|
+
|
|
19
|
+
__all__ = [
|
|
20
|
+
"ArkFile",
|
|
21
|
+
"Profile",
|
|
22
|
+
"Tribe",
|
|
23
|
+
"CloudInventory",
|
|
24
|
+
"WorldSave",
|
|
25
|
+
]
|