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
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Structure model class - Map structures (buildings, rafts, etc.).
|
|
3
|
+
|
|
4
|
+
Wraps GameObject with intuitive attribute access for structure data.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import typing as t
|
|
10
|
+
from dataclasses import dataclass, field
|
|
11
|
+
|
|
12
|
+
from .stats import Location
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@dataclass
|
|
16
|
+
class Structure:
|
|
17
|
+
"""
|
|
18
|
+
A placed structure (building piece, crafting station, etc.).
|
|
19
|
+
|
|
20
|
+
Wraps a GameObject representing a structure with intuitive property access.
|
|
21
|
+
|
|
22
|
+
Attributes:
|
|
23
|
+
class_name: Blueprint class name.
|
|
24
|
+
owner_tribe_id: ID of the owning tribe.
|
|
25
|
+
owner_tribe_name: Name of the owning tribe.
|
|
26
|
+
location: World position.
|
|
27
|
+
health: Current health.
|
|
28
|
+
max_health: Maximum health.
|
|
29
|
+
|
|
30
|
+
Example:
|
|
31
|
+
>>> for structure in save.structures:
|
|
32
|
+
... print(f"{structure.class_name} - {structure.owner_tribe_name}")
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
_game_object: t.Any = field(default=None, repr=False)
|
|
36
|
+
|
|
37
|
+
@classmethod
|
|
38
|
+
def from_game_object(cls, game_object: t.Any) -> Structure:
|
|
39
|
+
"""
|
|
40
|
+
Create a Structure from a GameObject.
|
|
41
|
+
|
|
42
|
+
Args:
|
|
43
|
+
game_object: The structure's game object.
|
|
44
|
+
|
|
45
|
+
Returns:
|
|
46
|
+
A Structure instance.
|
|
47
|
+
"""
|
|
48
|
+
return cls(_game_object=game_object)
|
|
49
|
+
|
|
50
|
+
@property
|
|
51
|
+
def class_name(self) -> str:
|
|
52
|
+
"""Blueprint class name."""
|
|
53
|
+
return self._game_object.class_name if self._game_object else ""
|
|
54
|
+
|
|
55
|
+
@property
|
|
56
|
+
def guid(self) -> str:
|
|
57
|
+
"""Unique identifier (ASA only)."""
|
|
58
|
+
return self._game_object.guid if self._game_object else ""
|
|
59
|
+
|
|
60
|
+
@property
|
|
61
|
+
def owner_tribe_id(self) -> int:
|
|
62
|
+
"""ID of the owning tribe."""
|
|
63
|
+
if not self._game_object:
|
|
64
|
+
return 0
|
|
65
|
+
val = self._game_object.get_property_value("TargetingTeam", default=0)
|
|
66
|
+
return int(val) if val else 0
|
|
67
|
+
|
|
68
|
+
@property
|
|
69
|
+
def owner_tribe_name(self) -> str:
|
|
70
|
+
"""Name of the owning tribe."""
|
|
71
|
+
if not self._game_object:
|
|
72
|
+
return ""
|
|
73
|
+
return self._game_object.get_property_value("OwnerName", default="") or ""
|
|
74
|
+
|
|
75
|
+
@property
|
|
76
|
+
def owner_name(self) -> str:
|
|
77
|
+
"""Name of the owner (player who placed it)."""
|
|
78
|
+
if not self._game_object:
|
|
79
|
+
return ""
|
|
80
|
+
return self._game_object.get_property_value("OwnerName", default="") or ""
|
|
81
|
+
|
|
82
|
+
@property
|
|
83
|
+
def health(self) -> float:
|
|
84
|
+
"""Current health."""
|
|
85
|
+
if not self._game_object:
|
|
86
|
+
return 0.0
|
|
87
|
+
val = self._game_object.get_property_value("Health", default=0.0)
|
|
88
|
+
return float(val) if val else 0.0
|
|
89
|
+
|
|
90
|
+
@property
|
|
91
|
+
def max_health(self) -> float:
|
|
92
|
+
"""Maximum health."""
|
|
93
|
+
if not self._game_object:
|
|
94
|
+
return 0.0
|
|
95
|
+
val = self._game_object.get_property_value("MaxHealth", default=0.0)
|
|
96
|
+
return float(val) if val else 0.0
|
|
97
|
+
|
|
98
|
+
@property
|
|
99
|
+
def location(self) -> Location | None:
|
|
100
|
+
"""World position and rotation."""
|
|
101
|
+
if self._game_object and self._game_object.location:
|
|
102
|
+
loc = self._game_object.location
|
|
103
|
+
return Location(
|
|
104
|
+
x=loc.x,
|
|
105
|
+
y=loc.y,
|
|
106
|
+
z=loc.z,
|
|
107
|
+
pitch=getattr(loc, "pitch", 0.0),
|
|
108
|
+
yaw=getattr(loc, "yaw", 0.0),
|
|
109
|
+
roll=getattr(loc, "roll", 0.0),
|
|
110
|
+
)
|
|
111
|
+
return None
|
|
112
|
+
|
|
113
|
+
@property
|
|
114
|
+
def is_powered(self) -> bool:
|
|
115
|
+
"""True if the structure is powered (for electrical structures)."""
|
|
116
|
+
if not self._game_object:
|
|
117
|
+
return False
|
|
118
|
+
return self._game_object.get_property_value("bIsPowered", default=False)
|
|
119
|
+
|
|
120
|
+
@property
|
|
121
|
+
def is_locked(self) -> bool:
|
|
122
|
+
"""True if the structure is locked (for doors, containers)."""
|
|
123
|
+
if not self._game_object:
|
|
124
|
+
return False
|
|
125
|
+
return self._game_object.get_property_value("bIsLocked", default=False)
|
|
126
|
+
|
|
127
|
+
@property
|
|
128
|
+
def decay_time(self) -> float:
|
|
129
|
+
"""Time until decay (in seconds)."""
|
|
130
|
+
if not self._game_object:
|
|
131
|
+
return 0.0
|
|
132
|
+
val = self._game_object.get_property_value("LastInAllyRangeTime", default=0.0)
|
|
133
|
+
return float(val) if val else 0.0
|
|
134
|
+
|
|
135
|
+
@property
|
|
136
|
+
def custom_name(self) -> str:
|
|
137
|
+
"""Custom name given to the structure (if renamed)."""
|
|
138
|
+
if not self._game_object:
|
|
139
|
+
return ""
|
|
140
|
+
return self._game_object.get_property_value("StructureName", default="") or ""
|
|
141
|
+
|
|
142
|
+
def get_property(self, name: str, index: int = 0, default: t.Any = None) -> t.Any:
|
|
143
|
+
"""
|
|
144
|
+
Get a raw property value from the underlying game object.
|
|
145
|
+
|
|
146
|
+
Args:
|
|
147
|
+
name: Property name.
|
|
148
|
+
index: Array index for repeated properties.
|
|
149
|
+
default: Value to return if not found.
|
|
150
|
+
|
|
151
|
+
Returns:
|
|
152
|
+
The property value.
|
|
153
|
+
"""
|
|
154
|
+
if self._game_object:
|
|
155
|
+
return self._game_object.get_property_value(name, default=default, index=index)
|
|
156
|
+
return default
|
|
157
|
+
|
|
158
|
+
def to_dict(self) -> dict[str, t.Any]:
|
|
159
|
+
"""Convert to dictionary matching C# ASV_Structures export format."""
|
|
160
|
+
result: dict[str, t.Any] = {
|
|
161
|
+
"tribeid": self.owner_tribe_id,
|
|
162
|
+
"tribe": self.owner_tribe_name,
|
|
163
|
+
"struct": self.class_name,
|
|
164
|
+
"name": self.custom_name,
|
|
165
|
+
}
|
|
166
|
+
if self.location:
|
|
167
|
+
result["location"] = self.location.to_dict()
|
|
168
|
+
result["ccc"] = self.location.ccc
|
|
169
|
+
if self.location.latitude is not None:
|
|
170
|
+
result["lat"] = self.location.latitude
|
|
171
|
+
if self.location.longitude is not None:
|
|
172
|
+
result["lon"] = self.location.longitude
|
|
173
|
+
return result
|
|
174
|
+
|
|
175
|
+
def __repr__(self) -> str:
|
|
176
|
+
return f"Structure({self.class_name!r})"
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Tribe model class - ARK tribe data.
|
|
3
|
+
|
|
4
|
+
Wraps tribe data with intuitive attribute access.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import re
|
|
10
|
+
import typing as t
|
|
11
|
+
from dataclasses import dataclass, field
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@dataclass
|
|
15
|
+
class TribeMember:
|
|
16
|
+
"""
|
|
17
|
+
A tribe member.
|
|
18
|
+
|
|
19
|
+
Attributes:
|
|
20
|
+
player_id: Unique player ID.
|
|
21
|
+
name: Player name.
|
|
22
|
+
rank: Rank within the tribe.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
player_id: int = 0
|
|
26
|
+
name: str = ""
|
|
27
|
+
rank: int = 0
|
|
28
|
+
|
|
29
|
+
def to_dict(self) -> dict[str, t.Any]:
|
|
30
|
+
"""Convert to dictionary."""
|
|
31
|
+
return {
|
|
32
|
+
"player_id": self.player_id,
|
|
33
|
+
"name": self.name,
|
|
34
|
+
"rank": self.rank,
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
@dataclass
|
|
39
|
+
class TribeLogEntry:
|
|
40
|
+
"""
|
|
41
|
+
A tribe log entry.
|
|
42
|
+
|
|
43
|
+
Log entries follow the format: "Day X, HH:MM:SS: <RichColor ...>message</>"
|
|
44
|
+
|
|
45
|
+
Attributes:
|
|
46
|
+
day: In-game day number.
|
|
47
|
+
time: Time string (HH:MM:SS).
|
|
48
|
+
message: Full raw log message (including rich color tags).
|
|
49
|
+
clean_message: Message with rich color tags stripped.
|
|
50
|
+
"""
|
|
51
|
+
|
|
52
|
+
day: int = 0
|
|
53
|
+
time: str = ""
|
|
54
|
+
message: str = ""
|
|
55
|
+
|
|
56
|
+
# Regex to parse "Day X, HH:MM:SS: rest"
|
|
57
|
+
_LOG_PATTERN: t.ClassVar[re.Pattern[str]] = re.compile(r"Day\s+(\d+),?\s+([\d:]+):\s*(.*)", re.DOTALL)
|
|
58
|
+
# Regex to strip RichColor tags
|
|
59
|
+
_RICH_COLOR_PATTERN: t.ClassVar[re.Pattern[str]] = re.compile(r"<RichColor[^>]*>|</>")
|
|
60
|
+
|
|
61
|
+
@classmethod
|
|
62
|
+
def from_string(cls, raw: str) -> TribeLogEntry:
|
|
63
|
+
"""
|
|
64
|
+
Parse a tribe log entry from a raw string.
|
|
65
|
+
|
|
66
|
+
Args:
|
|
67
|
+
raw: Raw log string (e.g., "Day 387, 22:35:36: message").
|
|
68
|
+
|
|
69
|
+
Returns:
|
|
70
|
+
A TribeLogEntry with parsed fields.
|
|
71
|
+
"""
|
|
72
|
+
match = cls._LOG_PATTERN.match(raw.strip())
|
|
73
|
+
if match:
|
|
74
|
+
return cls(
|
|
75
|
+
day=int(match.group(1)),
|
|
76
|
+
time=match.group(2),
|
|
77
|
+
message=raw.strip(),
|
|
78
|
+
)
|
|
79
|
+
return cls(message=raw.strip())
|
|
80
|
+
|
|
81
|
+
@property
|
|
82
|
+
def clean_message(self) -> str:
|
|
83
|
+
"""Message with RichColor XML tags stripped."""
|
|
84
|
+
match = self._LOG_PATTERN.match(self.message)
|
|
85
|
+
body = match.group(3) if match else self.message
|
|
86
|
+
return self._RICH_COLOR_PATTERN.sub("", body).strip()
|
|
87
|
+
|
|
88
|
+
def to_dict(self) -> dict[str, t.Any]:
|
|
89
|
+
"""Convert to dictionary."""
|
|
90
|
+
return {
|
|
91
|
+
"day": self.day,
|
|
92
|
+
"time": self.time,
|
|
93
|
+
"message": self.message,
|
|
94
|
+
"clean_message": self.clean_message,
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
@dataclass
|
|
99
|
+
class Tribe:
|
|
100
|
+
"""
|
|
101
|
+
An ARK tribe.
|
|
102
|
+
|
|
103
|
+
Wraps tribe data with intuitive property access.
|
|
104
|
+
|
|
105
|
+
Attributes:
|
|
106
|
+
tribe_id: Unique tribe identifier.
|
|
107
|
+
name: Tribe name.
|
|
108
|
+
owner_id: Player ID of the tribe owner.
|
|
109
|
+
members: List of tribe members.
|
|
110
|
+
log: List of tribe log entries.
|
|
111
|
+
|
|
112
|
+
Example:
|
|
113
|
+
>>> tribe = Tribe.from_game_object(obj)
|
|
114
|
+
>>> print(f"{tribe.name} (ID: {tribe.tribe_id})")
|
|
115
|
+
>>> print(f"Members: {len(tribe.members)}")
|
|
116
|
+
"""
|
|
117
|
+
|
|
118
|
+
_game_object: t.Any = field(default=None, repr=False)
|
|
119
|
+
|
|
120
|
+
# Cached values
|
|
121
|
+
_members: list[TribeMember] | None = field(default=None, repr=False)
|
|
122
|
+
_log: list[TribeLogEntry] | None = field(default=None, repr=False)
|
|
123
|
+
|
|
124
|
+
@classmethod
|
|
125
|
+
def from_game_object(cls, game_object: t.Any) -> Tribe:
|
|
126
|
+
"""
|
|
127
|
+
Create a Tribe from a GameObject.
|
|
128
|
+
|
|
129
|
+
Args:
|
|
130
|
+
game_object: The tribe's game object.
|
|
131
|
+
|
|
132
|
+
Returns:
|
|
133
|
+
A Tribe instance.
|
|
134
|
+
"""
|
|
135
|
+
return cls(_game_object=game_object)
|
|
136
|
+
|
|
137
|
+
@property
|
|
138
|
+
def guid(self) -> str:
|
|
139
|
+
"""Unique identifier (ASA only)."""
|
|
140
|
+
return self._game_object.guid if self._game_object else ""
|
|
141
|
+
|
|
142
|
+
@property
|
|
143
|
+
def tribe_id(self) -> int:
|
|
144
|
+
"""Unique tribe identifier."""
|
|
145
|
+
if not self._game_object:
|
|
146
|
+
return 0
|
|
147
|
+
val = self._game_object.get_property_value("TribeID", default=0)
|
|
148
|
+
return int(val) if val else 0
|
|
149
|
+
|
|
150
|
+
@property
|
|
151
|
+
def name(self) -> str:
|
|
152
|
+
"""Tribe name."""
|
|
153
|
+
if not self._game_object:
|
|
154
|
+
return ""
|
|
155
|
+
return self._game_object.get_property_value("TribeName", default="") or ""
|
|
156
|
+
|
|
157
|
+
@property
|
|
158
|
+
def owner_id(self) -> int:
|
|
159
|
+
"""Player ID of the tribe owner."""
|
|
160
|
+
if not self._game_object:
|
|
161
|
+
return 0
|
|
162
|
+
val = self._game_object.get_property_value("OwnerPlayerDataID", default=0)
|
|
163
|
+
return int(val) if val else 0
|
|
164
|
+
|
|
165
|
+
@property
|
|
166
|
+
def owner_name(self) -> str:
|
|
167
|
+
"""Name of the tribe owner."""
|
|
168
|
+
if not self._game_object:
|
|
169
|
+
return ""
|
|
170
|
+
return self._game_object.get_property_value("OwnerPlayerName", default="") or ""
|
|
171
|
+
|
|
172
|
+
@property
|
|
173
|
+
def member_count(self) -> int:
|
|
174
|
+
"""Number of tribe members (from MembersPlayerDataID count)."""
|
|
175
|
+
if not self._game_object:
|
|
176
|
+
return 0
|
|
177
|
+
count = 0
|
|
178
|
+
while True:
|
|
179
|
+
val = self._game_object.get_property_value("MembersPlayerDataID", index=count, default=None)
|
|
180
|
+
if val is None:
|
|
181
|
+
break
|
|
182
|
+
count += 1
|
|
183
|
+
return max(count, 1) # At least the owner
|
|
184
|
+
|
|
185
|
+
@property
|
|
186
|
+
def members(self) -> list[TribeMember]:
|
|
187
|
+
"""List of tribe members."""
|
|
188
|
+
if self._members is None:
|
|
189
|
+
self._members = []
|
|
190
|
+
if self._game_object:
|
|
191
|
+
i = 0
|
|
192
|
+
while True:
|
|
193
|
+
player_id = self._game_object.get_property_value("MembersPlayerDataID", index=i, default=None)
|
|
194
|
+
if player_id is None:
|
|
195
|
+
break
|
|
196
|
+
name = self._game_object.get_property_value("MembersPlayerName", index=i, default="") or ""
|
|
197
|
+
rank = self._game_object.get_property_value("MembersRankGroups", index=i, default=0) or 0
|
|
198
|
+
self._members.append(
|
|
199
|
+
TribeMember(
|
|
200
|
+
player_id=int(player_id),
|
|
201
|
+
name=name,
|
|
202
|
+
rank=int(rank) if rank else 0,
|
|
203
|
+
)
|
|
204
|
+
)
|
|
205
|
+
i += 1
|
|
206
|
+
return self._members
|
|
207
|
+
|
|
208
|
+
@property
|
|
209
|
+
def alliance_ids(self) -> list[int]:
|
|
210
|
+
"""IDs of allied tribes."""
|
|
211
|
+
if not self._game_object:
|
|
212
|
+
return []
|
|
213
|
+
ids = []
|
|
214
|
+
i = 0
|
|
215
|
+
while True:
|
|
216
|
+
val = self._game_object.get_property_value("TribeAlliances", index=i, default=None)
|
|
217
|
+
if val is None:
|
|
218
|
+
break
|
|
219
|
+
ids.append(int(val) if val else 0)
|
|
220
|
+
i += 1
|
|
221
|
+
return ids
|
|
222
|
+
|
|
223
|
+
@property
|
|
224
|
+
def log(self) -> list[TribeLogEntry]:
|
|
225
|
+
"""
|
|
226
|
+
Tribe log entries.
|
|
227
|
+
|
|
228
|
+
Parses the TribeLog property (array of strings) into
|
|
229
|
+
structured TribeLogEntry objects.
|
|
230
|
+
"""
|
|
231
|
+
if self._log is None:
|
|
232
|
+
self._log = []
|
|
233
|
+
if self._game_object:
|
|
234
|
+
log_val = self._game_object.get_property_value("TribeLog", default=None)
|
|
235
|
+
if isinstance(log_val, list):
|
|
236
|
+
for entry in log_val:
|
|
237
|
+
if isinstance(entry, str) and entry.strip():
|
|
238
|
+
self._log.append(TribeLogEntry.from_string(entry))
|
|
239
|
+
else:
|
|
240
|
+
# Try indexed access (some formats store as repeated props)
|
|
241
|
+
i = 0
|
|
242
|
+
while True:
|
|
243
|
+
val = self._game_object.get_property_value("TribeLog", index=i, default=None)
|
|
244
|
+
if val is None:
|
|
245
|
+
break
|
|
246
|
+
if isinstance(val, str) and val.strip():
|
|
247
|
+
self._log.append(TribeLogEntry.from_string(val))
|
|
248
|
+
i += 1
|
|
249
|
+
return self._log
|
|
250
|
+
|
|
251
|
+
@property
|
|
252
|
+
def raw_logs(self) -> list[str]:
|
|
253
|
+
"""
|
|
254
|
+
Raw tribe log strings (as stored in the save file).
|
|
255
|
+
|
|
256
|
+
Returns:
|
|
257
|
+
List of raw log message strings.
|
|
258
|
+
"""
|
|
259
|
+
return [entry.message for entry in self.log]
|
|
260
|
+
|
|
261
|
+
def get_property(self, name: str, index: int = 0, default: t.Any = None) -> t.Any:
|
|
262
|
+
"""
|
|
263
|
+
Get a raw property value from the underlying game object.
|
|
264
|
+
|
|
265
|
+
Args:
|
|
266
|
+
name: Property name.
|
|
267
|
+
index: Array index for repeated properties.
|
|
268
|
+
default: Value to return if not found.
|
|
269
|
+
|
|
270
|
+
Returns:
|
|
271
|
+
The property value.
|
|
272
|
+
"""
|
|
273
|
+
if self._game_object:
|
|
274
|
+
return self._game_object.get_property_value(name, default=default, index=index)
|
|
275
|
+
return default
|
|
276
|
+
|
|
277
|
+
def to_dict(self) -> dict[str, t.Any]:
|
|
278
|
+
"""Convert to dictionary matching C# ASV_Tribes export format."""
|
|
279
|
+
return {
|
|
280
|
+
"tribeid": self.tribe_id,
|
|
281
|
+
"tribe": self.name,
|
|
282
|
+
"players": self.member_count,
|
|
283
|
+
"members": [m.to_dict() for m in self.members],
|
|
284
|
+
"owner_id": self.owner_id,
|
|
285
|
+
"owner_name": self.owner_name,
|
|
286
|
+
"alliance_ids": self.alliance_ids,
|
|
287
|
+
"logs": self.raw_logs,
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
def __repr__(self) -> str:
|
|
291
|
+
return f"Tribe({self.name!r}, id={self.tribe_id}, members={self.member_count})"
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"""
|
|
2
|
+
ARK Property System.
|
|
3
|
+
|
|
4
|
+
This module provides the property parsing system for ARK save files.
|
|
5
|
+
Properties are the core data storage mechanism for game objects.
|
|
6
|
+
|
|
7
|
+
Usage:
|
|
8
|
+
from arkparser.properties import read_properties, read_properties_as_dict
|
|
9
|
+
|
|
10
|
+
# Read properties from binary data
|
|
11
|
+
properties = read_properties(reader, is_asa=False)
|
|
12
|
+
|
|
13
|
+
# Or as a dictionary for easier access
|
|
14
|
+
props_dict = read_properties_as_dict(reader, is_asa=False)
|
|
15
|
+
health = get_property_value(props_dict, "Health", default=100.0)
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
from .base import Property, PropertyHeader, read_property_header
|
|
19
|
+
from .byte_property import ByteProperty
|
|
20
|
+
from .compound import ArrayProperty, MapProperty, StructProperty
|
|
21
|
+
from .primitives import (
|
|
22
|
+
BoolProperty,
|
|
23
|
+
DoubleProperty,
|
|
24
|
+
FloatProperty,
|
|
25
|
+
Int8Property,
|
|
26
|
+
Int16Property,
|
|
27
|
+
Int64Property,
|
|
28
|
+
IntProperty,
|
|
29
|
+
NameProperty,
|
|
30
|
+
ObjectProperty,
|
|
31
|
+
SoftObjectProperty,
|
|
32
|
+
StrProperty,
|
|
33
|
+
UInt16Property,
|
|
34
|
+
UInt32Property,
|
|
35
|
+
UInt64Property,
|
|
36
|
+
)
|
|
37
|
+
from .registry import (
|
|
38
|
+
PROPERTY_REGISTRY,
|
|
39
|
+
get_property_value,
|
|
40
|
+
read_properties,
|
|
41
|
+
read_properties_as_dict,
|
|
42
|
+
read_property,
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
__all__ = [
|
|
46
|
+
# Base
|
|
47
|
+
"Property",
|
|
48
|
+
"PropertyHeader",
|
|
49
|
+
"read_property_header",
|
|
50
|
+
# Primitives
|
|
51
|
+
"Int8Property",
|
|
52
|
+
"Int16Property",
|
|
53
|
+
"IntProperty",
|
|
54
|
+
"Int64Property",
|
|
55
|
+
"UInt16Property",
|
|
56
|
+
"UInt32Property",
|
|
57
|
+
"UInt64Property",
|
|
58
|
+
"FloatProperty",
|
|
59
|
+
"DoubleProperty",
|
|
60
|
+
"BoolProperty",
|
|
61
|
+
"StrProperty",
|
|
62
|
+
"NameProperty",
|
|
63
|
+
"ObjectProperty",
|
|
64
|
+
"SoftObjectProperty",
|
|
65
|
+
# Byte
|
|
66
|
+
"ByteProperty",
|
|
67
|
+
# Compound
|
|
68
|
+
"ArrayProperty",
|
|
69
|
+
"StructProperty",
|
|
70
|
+
"MapProperty",
|
|
71
|
+
# Registry
|
|
72
|
+
"PROPERTY_REGISTRY",
|
|
73
|
+
"read_property",
|
|
74
|
+
"read_properties",
|
|
75
|
+
"read_properties_as_dict",
|
|
76
|
+
"get_property_value",
|
|
77
|
+
]
|