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,227 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Character model class - Player characters in world saves.
|
|
3
|
+
|
|
4
|
+
Wraps GameObject with intuitive attribute access for character 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 CreatureStats, Location
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@dataclass
|
|
16
|
+
class Character:
|
|
17
|
+
"""
|
|
18
|
+
A player character in a world save.
|
|
19
|
+
|
|
20
|
+
Wraps a GameObject representing a player character with intuitive property access.
|
|
21
|
+
This differs from Player (profile data) - Character is the in-world entity.
|
|
22
|
+
|
|
23
|
+
Attributes:
|
|
24
|
+
class_name: Blueprint class name.
|
|
25
|
+
player_name: Character name.
|
|
26
|
+
tribe_id: ID of the player's tribe.
|
|
27
|
+
tribe_name: Name of the player's tribe.
|
|
28
|
+
level: Character level.
|
|
29
|
+
location: World position.
|
|
30
|
+
|
|
31
|
+
Example:
|
|
32
|
+
>>> for character in save.characters:
|
|
33
|
+
... print(f"{character.player_name} - Level {character.level}")
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
_game_object: t.Any = field(default=None, repr=False)
|
|
37
|
+
_status_object: t.Any = field(default=None, repr=False)
|
|
38
|
+
|
|
39
|
+
# Cached values
|
|
40
|
+
_stats: CreatureStats | None = field(default=None, repr=False)
|
|
41
|
+
|
|
42
|
+
@classmethod
|
|
43
|
+
def from_game_object(
|
|
44
|
+
cls,
|
|
45
|
+
game_object: t.Any,
|
|
46
|
+
status_object: t.Any = None,
|
|
47
|
+
) -> Character:
|
|
48
|
+
"""
|
|
49
|
+
Create a Character from a GameObject.
|
|
50
|
+
|
|
51
|
+
Args:
|
|
52
|
+
game_object: The character's main game object.
|
|
53
|
+
status_object: The character's status component (for stats).
|
|
54
|
+
|
|
55
|
+
Returns:
|
|
56
|
+
A Character instance.
|
|
57
|
+
"""
|
|
58
|
+
return cls(_game_object=game_object, _status_object=status_object)
|
|
59
|
+
|
|
60
|
+
@property
|
|
61
|
+
def class_name(self) -> str:
|
|
62
|
+
"""Blueprint class name."""
|
|
63
|
+
return self._game_object.class_name if self._game_object else ""
|
|
64
|
+
|
|
65
|
+
@property
|
|
66
|
+
def guid(self) -> str:
|
|
67
|
+
"""Unique identifier (ASA only)."""
|
|
68
|
+
return self._game_object.guid if self._game_object else ""
|
|
69
|
+
|
|
70
|
+
@property
|
|
71
|
+
def player_id(self) -> int:
|
|
72
|
+
"""Unique player ID."""
|
|
73
|
+
if not self._game_object:
|
|
74
|
+
return 0
|
|
75
|
+
val = self._game_object.get_property_value("LinkedPlayerDataID", default=0)
|
|
76
|
+
if not val:
|
|
77
|
+
val = self._game_object.get_property_value("PlayerDataID", default=0)
|
|
78
|
+
return int(val) if val else 0
|
|
79
|
+
|
|
80
|
+
@property
|
|
81
|
+
def player_name(self) -> str:
|
|
82
|
+
"""Character name."""
|
|
83
|
+
if not self._game_object:
|
|
84
|
+
return ""
|
|
85
|
+
name = self._game_object.get_property_value("PlayerName", default="")
|
|
86
|
+
if not name:
|
|
87
|
+
name = self._game_object.get_property_value("LinkedPlayerName", default="")
|
|
88
|
+
return name or ""
|
|
89
|
+
|
|
90
|
+
@property
|
|
91
|
+
def steam_name(self) -> str:
|
|
92
|
+
"""Steam/platform username."""
|
|
93
|
+
if not self._game_object:
|
|
94
|
+
return ""
|
|
95
|
+
return self._game_object.get_property_value("PlatformProfileName", default="") or ""
|
|
96
|
+
|
|
97
|
+
@property
|
|
98
|
+
def tribe_id(self) -> int:
|
|
99
|
+
"""Tribe ID the character belongs to."""
|
|
100
|
+
if not self._game_object:
|
|
101
|
+
return 0
|
|
102
|
+
val = self._game_object.get_property_value("TargetingTeam", default=0)
|
|
103
|
+
if not val:
|
|
104
|
+
val = self._game_object.get_property_value("TribeID", default=0)
|
|
105
|
+
return int(val) if val else 0
|
|
106
|
+
|
|
107
|
+
@property
|
|
108
|
+
def tribe_name(self) -> str:
|
|
109
|
+
"""Name of the character's tribe."""
|
|
110
|
+
if not self._game_object:
|
|
111
|
+
return ""
|
|
112
|
+
return self._game_object.get_property_value("TribeName", default="") or ""
|
|
113
|
+
|
|
114
|
+
@property
|
|
115
|
+
def is_female(self) -> bool:
|
|
116
|
+
"""True if the character is female."""
|
|
117
|
+
if not self._game_object:
|
|
118
|
+
return False
|
|
119
|
+
return self._game_object.get_property_value("bIsFemale", default=False)
|
|
120
|
+
|
|
121
|
+
@property
|
|
122
|
+
def gender(self) -> str:
|
|
123
|
+
"""Gender as string ('Female' or 'Male')."""
|
|
124
|
+
return "Female" if self.is_female else "Male"
|
|
125
|
+
|
|
126
|
+
@property
|
|
127
|
+
def base_level(self) -> int:
|
|
128
|
+
"""Base character level."""
|
|
129
|
+
if self._status_object:
|
|
130
|
+
return self._status_object.get_property_value("BaseCharacterLevel", default=1)
|
|
131
|
+
return 1
|
|
132
|
+
|
|
133
|
+
@property
|
|
134
|
+
def extra_level(self) -> int:
|
|
135
|
+
"""Extra levels (ascension levels, etc.)."""
|
|
136
|
+
if self._status_object:
|
|
137
|
+
val = self._status_object.get_property_value("ExtraCharacterLevel", default=0)
|
|
138
|
+
return int(val) if val else 0
|
|
139
|
+
return 0
|
|
140
|
+
|
|
141
|
+
@property
|
|
142
|
+
def level(self) -> int:
|
|
143
|
+
"""Total character level."""
|
|
144
|
+
return self.base_level + self.extra_level
|
|
145
|
+
|
|
146
|
+
@property
|
|
147
|
+
def experience(self) -> float:
|
|
148
|
+
"""Current experience points."""
|
|
149
|
+
if self._status_object:
|
|
150
|
+
val = self._status_object.get_property_value("ExperiencePoints", default=0.0)
|
|
151
|
+
return float(val) if val else 0.0
|
|
152
|
+
return 0.0
|
|
153
|
+
|
|
154
|
+
@property
|
|
155
|
+
def stats(self) -> CreatureStats:
|
|
156
|
+
"""
|
|
157
|
+
Character stat points.
|
|
158
|
+
|
|
159
|
+
Uses the same 12-stat system as creatures.
|
|
160
|
+
"""
|
|
161
|
+
if self._stats is None:
|
|
162
|
+
points = []
|
|
163
|
+
if self._status_object:
|
|
164
|
+
for i in range(12):
|
|
165
|
+
val = self._status_object.get_property_value("NumberOfLevelUpPointsApplied", index=i, default=0)
|
|
166
|
+
points.append(int(val) if val else 0)
|
|
167
|
+
self._stats = CreatureStats.from_array(points)
|
|
168
|
+
return self._stats
|
|
169
|
+
|
|
170
|
+
@property
|
|
171
|
+
def location(self) -> Location | None:
|
|
172
|
+
"""World position and rotation."""
|
|
173
|
+
if self._game_object and self._game_object.location:
|
|
174
|
+
loc = self._game_object.location
|
|
175
|
+
return Location(
|
|
176
|
+
x=loc.x,
|
|
177
|
+
y=loc.y,
|
|
178
|
+
z=loc.z,
|
|
179
|
+
pitch=getattr(loc, "pitch", 0.0),
|
|
180
|
+
yaw=getattr(loc, "yaw", 0.0),
|
|
181
|
+
roll=getattr(loc, "roll", 0.0),
|
|
182
|
+
)
|
|
183
|
+
return None
|
|
184
|
+
|
|
185
|
+
@property
|
|
186
|
+
def is_sleeping(self) -> bool:
|
|
187
|
+
"""True if the character is sleeping (logged out)."""
|
|
188
|
+
if not self._game_object:
|
|
189
|
+
return False
|
|
190
|
+
return self._game_object.get_property_value("bIsSleeping", default=False)
|
|
191
|
+
|
|
192
|
+
def get_property(self, name: str, index: int = 0, default: t.Any = None) -> t.Any:
|
|
193
|
+
"""
|
|
194
|
+
Get a raw property value from the underlying game object.
|
|
195
|
+
|
|
196
|
+
Args:
|
|
197
|
+
name: Property name.
|
|
198
|
+
index: Array index for repeated properties.
|
|
199
|
+
default: Value to return if not found.
|
|
200
|
+
|
|
201
|
+
Returns:
|
|
202
|
+
The property value.
|
|
203
|
+
"""
|
|
204
|
+
if self._game_object:
|
|
205
|
+
return self._game_object.get_property_value(name, default=default, index=index)
|
|
206
|
+
return default
|
|
207
|
+
|
|
208
|
+
def to_dict(self) -> dict[str, t.Any]:
|
|
209
|
+
"""Convert to dictionary."""
|
|
210
|
+
result: dict[str, t.Any] = {
|
|
211
|
+
"player_id": self.player_id,
|
|
212
|
+
"player_name": self.player_name,
|
|
213
|
+
"gender": self.gender,
|
|
214
|
+
"level": self.level,
|
|
215
|
+
"experience": self.experience,
|
|
216
|
+
"stats": self.stats.to_dict(),
|
|
217
|
+
"tribe_id": self.tribe_id,
|
|
218
|
+
"tribe_name": self.tribe_name,
|
|
219
|
+
}
|
|
220
|
+
if self.steam_name:
|
|
221
|
+
result["steam_name"] = self.steam_name
|
|
222
|
+
if self.location:
|
|
223
|
+
result["location"] = self.location.to_dict()
|
|
224
|
+
return result
|
|
225
|
+
|
|
226
|
+
def __repr__(self) -> str:
|
|
227
|
+
return f"Character({self.player_name!r}, level={self.level})"
|