Skip to content

Commit a449a4f

Browse files
committed
V1.1 - pep8
UnityPy is now pep8 conform. Object load became 10~20% faster due to a TypeTreeHelper change. Enums have a default option for unknown entries.
1 parent 65903c8 commit a449a4f

24 files changed

Lines changed: 1161 additions & 1308 deletions

UnityPy/AssetsManager.py

Lines changed: 100 additions & 171 deletions
Original file line numberDiff line numberDiff line change
@@ -1,219 +1,148 @@
11
import os
2-
from .helpers import ImportHelper
2+
33
from .EndianBinaryReader import EndianBinaryReader
4-
from .Progress import Progress
54
from .Logger import Logger
5+
from .Progress import Progress
66
from .files import BundleFile, SerializedFile, WebFile
7-
from .ObjectReader import ObjectReader
8-
from .Object import Object
9-
from . import classes
7+
from .helpers import ImportHelper
108

119
FileType = ImportHelper.FileType
1210

1311

14-
class AssetsManager():
15-
assetsFileList = []
16-
assetsFileIndexCache = {}
17-
resourceFileReaders = {}
12+
class AssetsManager:
13+
assets :dict = {}
14+
resource_file_readers = {}
1815

19-
importFiles = []
20-
importFilesHash = []
21-
assetsFileListHash = []
16+
import_files : dict = {}
2217
Progress = Progress()
2318
Logger = Logger()
2419

25-
def LoadFiles(self, files):
20+
def load_files(self, files):
21+
"""Loads all files (list) into the AssetsManager and merges .split files for common usage."""
2622
path = os.path.dirname(files[0])
27-
ImportHelper.MergeSplitAssets(path)
28-
toReadFile = ImportHelper.ProcessingSplitFiles(files)
29-
self.Load(toReadFile)
23+
ImportHelper.merge_split_assets(path)
24+
to_read_file = ImportHelper.processing_split_files(files)
25+
self.load(to_read_file)
3026

31-
def LoadFolder(self, path):
32-
ImportHelper.MergeSplitAssets(path, True)
33-
files = ImportHelper.ListAllFiles(path)
34-
toReadFile = ImportHelper.ProcessingSplitFiles(files)
35-
self.Load(toReadFile)
27+
def load_folder(self, path):
28+
"""Loads all files in the given path and its subdirs into the AssetsManager."""
29+
ImportHelper.merge_split_assets(path, True)
30+
files = ImportHelper.list_all_files(path)
31+
to_read_file = ImportHelper.processing_split_files(files)
32+
self.load(to_read_file)
3633

37-
def Load(self, files):
34+
def load(self, files):
35+
"""Loads all files into the AssetsManager."""
3836
for f in files:
39-
self.importFiles.append(f)
40-
self.importFilesHash.append(os.path.basename(f).upper())
37+
self.import_files[os.path.basename(f)] = f
4138

42-
self.Progress.Reset()
39+
self.Progress.reset()
4340
# use a for loop because list size can change
44-
for i, f in enumerate(self.importFiles):
45-
self.LoadFile(f)
46-
self.Progress.Report(i + 1, len(self.importFiles))
47-
48-
self.importFiles = []
49-
self.importFilesHash = []
50-
self.assetsFileListHash = []
51-
52-
self.ReadAssets()
41+
for i, f in enumerate(self.import_files.values()):
42+
self.load_file(f)
43+
self.Progress.report(i + 1, len(self.import_files))
5344

54-
# self.ProcessGameObject()
55-
56-
def LoadFile(self, fullName):
57-
typ, reader = ImportHelper.CheckFileType(fullName)
45+
def load_file(self, full_name):
46+
typ, reader = ImportHelper.check_file_type(full_name)
47+
if type(full_name) != str:
48+
full_name = str(full_name)
5849
if typ == FileType.AssetsFile:
59-
self.LoadAssetsFile(fullName, reader)
50+
self.load_assets_file(full_name, reader)
6051
elif typ == FileType.BundleFile:
61-
self.LoadBundleFile(fullName, reader)
52+
self.load_bundle_file(full_name, reader)
6253
elif FileType.WebFile:
63-
self.LoadWebFile(fullName, reader)
54+
self.load_web_file(full_name, reader)
6455

65-
def LoadAssetsFile(self, fullName, reader):
66-
fileName = os.path.basename(fullName)
67-
if fileName.upper() not in self.assetsFileListHash:
68-
self.Logger.Info(f"Loading {fullName}")
56+
def load_assets_file(self, full_name, reader):
57+
file_name = os.path.basename(full_name)
58+
if file_name not in self.assets:
59+
self.Logger.info(f"Loading {full_name}")
6960
try:
70-
assetsFile = SerializedFile(self, fullName, reader)
71-
self.assetsFileList.append(assetsFile)
72-
self.assetsFileListHash.append(assetsFile.upperFileName)
61+
assets_file = SerializedFile(self, full_name, reader)
62+
self.assets[assets_file.name] = assets_file
7363

74-
for sharedFile in assetsFile.m_Externals:
75-
sharedFilePath = os.path.join(os.path.dirname(fullName), sharedFile.fileName)
76-
sharedFileName = sharedFile.fileName
64+
for sharedFile in assets_file._externals:
65+
shared_file_path = os.path.join(os.path.dirname(full_name), sharedFile.file_name)
66+
shared_file_name = sharedFile.file_name
7767

78-
if sharedFileName.upper() not in self.importFilesHash:
79-
if not os.path.exists(sharedFilePath):
80-
findFiles = [f for f in ImportHelper.ListAllFiles(os.path.dirname(fullName)) if sharedFileName in f]
81-
if findFiles:
82-
sharedFilePath = findFiles[0]
68+
if shared_file_name not in self.import_files:
69+
if not os.path.exists(shared_file_path):
70+
find_files = [f for f in ImportHelper.list_all_files(os.path.dirname(full_name)) if shared_file_name in f]
71+
if find_files:
72+
shared_file_path = find_files[0]
8373

84-
if os.path.exists(sharedFilePath):
85-
self.importFiles.append(sharedFilePath)
86-
self.importFilesHash.append(sharedFileName.upper())
74+
if os.path.exists(shared_file_path):
75+
self.import_files[shared_file_name] = shared_file_path
8776

88-
except:
89-
reader.Dispose()
90-
self.Logger.Error(f"Unable to load assets file {fileName}")
77+
except Exception as e:
78+
reader.dispose()
79+
self.Logger.error(f"Unable to load assets file {file_name}", e)
9180
else:
92-
reader.Dispose()
93-
return assetsFile
81+
reader.dispose()
82+
return assets_file
9483

95-
def LoadAssetsFromMemory(self, fullName, reader, originalPath, unityVersion = None):
96-
upperFileName = os.path.basename(fullName).upper()
97-
if upperFileName not in self.assetsFileListHash:
84+
def load_assets_from_memory(self, full_name, reader, original_path, unity_version = None):
85+
file_name = os.path.basename(full_name)
86+
if file_name not in self.assets:
9887
try:
99-
assetsFile = SerializedFile(self, fullName, reader)
100-
assetsFile.originalPath = originalPath
101-
if assetsFile.header.m_Version < 7:
102-
assetsFile.SetVersion(unityVersion)
103-
self.assetsFileList.append(assetsFile)
104-
self.assetsFileListHash.append(upperFileName)
105-
except:
106-
if '.RESS' != upperFileName[-5:]:
107-
self.Logger.Error(f"Unable to load assets file {upperFileName} from {originalPath}")
88+
assets_file = SerializedFile(self, full_name, reader)
89+
assets_file.original_path = original_path
90+
if assets_file.header.version < 7:
91+
assets_file.set_version(unity_version)
92+
self.assets[file_name] = assets_file
93+
except Exception as e:
94+
self.Logger.error(f"Unable to load assets file {file_name} from {original_path}", e)
10895
finally:
109-
self.resourceFileReaders[upperFileName] = reader
96+
self.resource_file_readers[file_name] = reader
11097

111-
def LoadBundleFile(self, fullName, reader, parentPath = None):
112-
fileName = os.path.basename(fullName)
113-
self.Logger.Info(f"Loading {fullName}")
98+
def load_bundle_file(self, full_name, reader, parent_path = None):
99+
file_name = os.path.basename(full_name)
100+
self.Logger.info(f"Loading {full_name}")
101+
bundle_file = None
114102
try:
115-
bundleFile = BundleFile(reader, fullName)
116-
for f in bundleFile.fileList:
117-
dummyPath = os.path.join(os.path.dirname(fullName), f.fileName)
118-
self.LoadAssetsFromMemory(dummyPath, EndianBinaryReader(f.stream), fullName if parentPath else bundleFile.versionEngine)
119-
except:
120-
string = f"Unable to load bundle file {fileName}"
121-
if parentPath:
122-
string += f" from {os.path.basename(parentPath)}"
123-
self.Logger.Error(string)
103+
bundle_file = BundleFile(reader, full_name)
104+
for f in bundle_file.files:
105+
dummy_path = os.path.join(os.path.dirname(full_name), f.file_name)
106+
self.load_assets_from_memory(dummy_path, EndianBinaryReader(f.stream), full_name if parent_path else bundle_file.version_engine)
107+
except Exception as e:
108+
string = f"Unable to load bundle file {file_name}"
109+
if parent_path:
110+
string += f" from {os.path.basename(parent_path)}"
111+
string += '\n' + str(e)
112+
self.Logger.error(string, e)
124113
finally:
125-
reader.Dispose()
126-
return bundleFile
114+
reader.dispose()
115+
return bundle_file
127116

128-
def LoadWebFile(self, fullName, reader):
129-
fileName = os.path.basename(fullName)
130-
self.Logger.Info(f"Loading {fullName}")
117+
def load_web_file(self, full_name, reader):
118+
file_name = os.path.basename(full_name)
119+
self.Logger.info(f"Loading {full_name}")
131120
try:
132-
webFile = WebFile(reader)
133-
for f in webFile.fileList:
134-
dummyPath = os.path.join(os.path.dirname(fullName), f.fileName)
135-
typ, reader = ImportHelper.CheckFileType(f.stream)
121+
web_file = WebFile(reader)
122+
for f in web_file.files:
123+
dummy_path = os.path.join(os.path.dirname(full_name), f.name)
124+
typ, reader = ImportHelper.check_file_type(f.stream)
136125
if typ == FileType.AssetsFile:
137-
self.LoadAssetsFromMemory(dummyPath, reader, fullName)
126+
self.load_assets_from_memory(dummy_path, reader, full_name)
138127
elif typ == FileType.BundleFile:
139-
self.LoadBundleFile(dummyPath, reader, fullName)
128+
self.load_bundle_file(dummy_path, reader, full_name)
140129
elif typ == FileType.WebFile:
141-
self.LoadWebFile(dummyPath, reader)
130+
self.load_web_file(dummy_path, reader)
142131

143-
except:
144-
self.Logger.Error(f"Unable to load web file {fileName}")
132+
except Exception as e:
133+
self.Logger.error(f"Unable to load web file {file_name}", e)
145134
finally:
146-
reader.Dispose()
147-
return webFile
135+
reader.dispose()
136+
return web_file
148137

149-
def Clear(self):
150-
for assetsFile in self.assetsFileList:
138+
def clear(self):
139+
for assetsFile in self.assets:
151140
assetsFile.Objects = []
152141
assetsFile.reader.Close()
153-
self.assetsFileList = []
142+
self.assets = []
154143

155-
for resourceFileReader in self.resourceFileReaders:
144+
for resourceFileReader in self.resource_file_readers:
156145
resourceFileReader.Value.Close()
157146

158-
self.resourceFileReaders = {}
159-
self.assetsFileIndexCache = []
160-
161-
def ReadAssets(self):
162-
self.Logger.Info("Read assets...")
163-
progressCount = sum([len(af.m_Objects) for af in self.assetsFileList])
164-
i = 0
165-
self.Progress.Reset()
166-
for assetsFile in self.assetsFileList:
167-
assetsFile.Objects = {}
168-
for objectInfo in assetsFile.m_Objects:
169-
objectReader = ObjectReader(assetsFile.reader, assetsFile, objectInfo)
170-
assetsFile.Objects[objectInfo.m_PathID] = objectReader.Read()
171-
self.Progress.Report(i, progressCount)
172-
173-
174-
175-
'''
176-
private void ProcessGameObject()
177-
{
178-
Logger.Info("Process GameObject...");
179-
180-
foreach (var assetsFile in assetsFileList)
181-
{
182-
foreach (var obj in assetsFile.Objects.Values)
183-
{
184-
if (obj is GameObject m_GameObject)
185-
{
186-
foreach (var pptr in m_GameObject.m_Components)
187-
{
188-
if (pptr.TryGet(out var m_Component))
189-
{
190-
switch (m_Component)
191-
{
192-
case Transform m_Transform:
193-
m_GameObject.m_Transform = m_Transform;
194-
break;
195-
case MeshRenderer m_MeshRenderer:
196-
m_GameObject.m_MeshRenderer = m_MeshRenderer;
197-
break;
198-
case MeshFilter m_MeshFilter:
199-
m_GameObject.m_MeshFilter = m_MeshFilter;
200-
break;
201-
case SkinnedMeshRenderer m_SkinnedMeshRenderer:
202-
m_GameObject.m_SkinnedMeshRenderer = m_SkinnedMeshRenderer;
203-
break;
204-
case Animator m_Animator:
205-
m_GameObject.m_Animator = m_Animator;
206-
break;
207-
case Animation m_Animation:
208-
m_GameObject.m_Animation = m_Animation;
209-
break;
210-
}
211-
}
212-
}
213-
}
214-
}
215-
}
216-
}
217-
}
218-
}
219-
'''
147+
self.resource_file_readers = {}
148+
self.assets_index_cache = []

UnityPy/CommonString.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
CommonString = {
1+
COMMON_STRING = {
22
0 : "AABB",
33
5 : "AnimationClip",
44
19 : "AnimationCurve",
@@ -32,25 +32,25 @@
3232
256 : "MdFour",
3333
263 : "MonoBehaviour",
3434
277 : "MonoScript",
35-
288 : "m_ByteSize",
35+
288 : "byte_size",
3636
299 : "m_Curve",
3737
307 : "m_EditorClassIdentifier",
3838
331 : "m_EditorHideFlags",
3939
349 : "m_Enabled",
4040
359 : "m_ExtensionPtr",
4141
374 : "m_GameObject",
42-
387 : "m_Index",
43-
395 : "m_IsArray",
42+
387 : "index",
43+
395 : "is_array",
4444
405 : "m_IsStatic",
45-
416 : "m_MetaFlag",
46-
427 : "m_Name",
47-
434 : "m_ObjectHideFlags",
45+
416 : "meta_flag",
46+
427 : "name",
47+
434 : "_object_hide_flags",
4848
452 : "m_PrefabInternal",
4949
469 : "m_PrefabParentObject",
5050
490 : "m_Script",
5151
499 : "m_StaticEditorFlags",
52-
519 : "m_Type",
53-
526 : "m_Version",
52+
519 : "type",
53+
526 : "version",
5454
536 : "Object",
5555
543 : "pair",
5656
548 : "PPtr<Component>",

0 commit comments

Comments
 (0)