forked from K0lb3/UnityPy
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPPtr.py
More file actions
85 lines (74 loc) · 3.15 KB
/
PPtr.py
File metadata and controls
85 lines (74 loc) · 3.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
from ..files import ObjectReader
from ..streams import EndianBinaryWriter
from ..helpers import ImportHelper
from .. import files
from ..enums import FileType, ClassIDType
import os
from .. import environment
def save_ptr(obj, writer: EndianBinaryWriter):
if isinstance(obj, PPtr):
writer.write_int(obj.file_id)
else:
writer.write_int(0) # it's usually 0......
if obj._version < 14:
writer.write_int(obj.path_id)
else:
writer.write_long(obj.path_id)
cached_managers = dict()
class PPtr:
def __init__(self, reader: ObjectReader):
self._version = reader.version2
self.index = -2
self.file_id = reader.read_int()
self.path_id = reader.read_int() if self._version < 14 else reader.read_long()
self.assets_file = reader.assets_file
self._obj = None
def save(self, writer: EndianBinaryWriter):
save_ptr(self, writer)
def get_obj(self):
if self._obj != None:
return self._obj
manager = None
if self.file_id == 0:
manager = self.assets_file
elif self.file_id > 0 and self.file_id - 1 < len(self.assets_file.externals):
if self.index == -2:
external_name = self.assets_file.externals[self.file_id - 1].name
parent = self.assets_file.parent
if parent is not None:
if external_name in parent.files:
manager = parent.files[external_name]
elif external_name.upper() in parent.files:
manager = parent.files[external_name.upper()]
else:
while not isinstance(parent, environment.Environment):
parent = parent.parent
if parent.path:
path = parent.path
files = os.listdir(path)
if external_name in files:
parent.load_files([os.path.join(path, external_name)])
manager = parent.files[external_name]
else:
if external_name not in cached_managers:
typ, reader = ImportHelper.check_file_type(external_name)
if typ == FileType.AssetsFile:
cached_managers[external_name] = files.SerializedFile(reader)
if external_name in cached_managers:
manager = cached_managers[external_name]
if manager and self.path_id in manager.objects:
self._obj = manager.objects[self.path_id]
else:
self._obj = None
return self._obj
def __getattr__(self, key):
obj = self.get_obj()
if obj is None:
if key == "type":
return ClassIDType.UnknownType
raise AttributeError(key)
return getattr(obj, key)
def __repr__(self):
return "<%s %s>" % (self.__class__.__name__, self._obj.__class__.__repr__(self.get_obj()) if self.get_obj() else "Not Found")
def __bool__(self):
return True if self.get_obj() else False