Skip to content

Commit 0fee975

Browse files
committed
improve folder splitfile handling
1 parent 7b7a26c commit 0fee975

3 files changed

Lines changed: 44 additions & 37 deletions

File tree

001_2018_dog

644 KB
Binary file not shown.

UnityPy/environment.py

Lines changed: 44 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from .streams import EndianBinaryReader
1111
from .files import SerializedFile
1212

13-
reSplit = re.compile(r"(.+/(\w+?\.split))\d+")
13+
reSplit = re.compile(r"(.+[/\\](\w+?\.split))\d+")
1414

1515

1616
class Environment:
@@ -50,33 +50,32 @@ def load_files(self, files: list):
5050
"""Loads all files (list) into the AssetsManager and merges .split files for common usage."""
5151
# filter split files
5252
i = 0
53-
splits = []
54-
while i < len(files):
55-
path = files[i]
56-
splitMatch = reSplitFile.match(path)
57-
if reSplitFile.match(path):
58-
name = splitMatch[1]
59-
if name not in splits:
60-
splits.append(name)
61-
files.remove(path)
53+
split_files = []
54+
for path in files:
55+
splitMatch = reSplit.match(path)
56+
if splitMatch:
57+
data = []
58+
basepath, basename = splitMatch.groups()
59+
60+
if basepath in split_files:
61+
continue
62+
63+
split_files.append(basepath)
64+
data = []
65+
for i in range(0, 999):
66+
item = f"{basepath}.split{i}"
67+
if item in files:
68+
with open(item, "rb") as f:
69+
data.append(f.read())
70+
elif i:
71+
break
72+
data = b"".join(data)
73+
74+
self.files[basepath] = self.load_file(data, self, basename)
6275
else:
63-
i += 1
64-
65-
# merge splits
66-
for basepath in splits:
67-
# merge data
68-
data = io.BytesIO()
69-
for i in range(0, 999):
70-
item = f"{basepath}.split{i}"
71-
if os.path.exists(item):
72-
with open(item, "rb") as f:
73-
data.write(f.read())
74-
elif i:
75-
break
76-
self.files[self.reduce_path(basepath)] = self.load_file(data)
77-
78-
# load all other files
79-
self.load(files)
76+
self.files[path] = self.cabs[os.path.basename(path)] = self.load_file(
77+
open(path, "rb").read(), self, path
78+
)
8079

8180
def load_folder(self, path: str):
8281
"""Loads all files in the given path and its subdirs into the AssetsManager."""
@@ -95,32 +94,40 @@ def load(self, files: list):
9594
"""Loads all files into the AssetsManager."""
9695
self.files.update(
9796
{
98-
self.reduce_path(f): self.load_file(open(f, "rb"))
97+
self.reduce_path(f): self.load_file(open(f, "rb"), self, f)
9998
for f in files
10099
if os.path.exists(f)
101100
}
102101
)
103102

104-
def load_file(self, stream, parent=None):
103+
def load_file(self, stream, parent=None, name: str = None):
105104
if not parent:
106105
parent = self
107106
typ, reader = ImportHelper.check_file_type(stream)
108107
try:
109-
stream_name = getattr(
110-
stream,
111-
"name",
112-
str(stream.__hash__()) if hasattr(stream, "__hash__") else "",
108+
stream_name = (
109+
name
110+
if name
111+
else getattr(
112+
stream,
113+
"name",
114+
str(stream.__hash__()) if hasattr(stream, "__hash__") else "",
115+
)
113116
)
114117
if typ == FileType.AssetsFile:
115-
return files.SerializedFile(reader, parent, name=stream_name)
118+
f = files.SerializedFile(reader, parent, name=stream_name)
119+
self.register_cab(stream_name, f)
120+
return f
116121
elif typ == FileType.BundleFile:
117122
return files.BundleFile(reader, parent, name=stream_name)
118123
elif typ == FileType.WebFile:
119124
return files.WebFile(reader, parent, name=stream_name)
120125
elif typ == FileType.ZIP:
121126
self.load_zip_file(stream)
122127
elif typ == FileType.ResourceFile:
123-
return EndianBinaryReader(stream)
128+
f = EndianBinaryReader(stream)
129+
self.register_cab(stream_name, f)
130+
return f
124131
except Exception as e:
125132
# just to be sure
126133
# cuz the SerializedFile detection isn't perfect
@@ -226,7 +233,7 @@ def get(self, key: str, default=None):
226233
return getattr(self, key, default)
227234

228235
def register_cab(self, name: str, item: object) -> None:
229-
self.cabs[name.lower()] = item
236+
self.cabs[os.path.basename(name.lower())] = item
230237

231238
def get_cab(self, name: str) -> object:
232-
return self.cabs.get(name.lower(), None)
239+
return self.cabs.get(os.path.basename(name.lower()), None)

demo.res

908 KB
Binary file not shown.

0 commit comments

Comments
 (0)