Skip to content

Commit 8eb6a5e

Browse files
committed
fix(environment)!: path & container
1 parent ea2f0d3 commit 8eb6a5e

File tree

1 file changed

+37
-28
lines changed

1 file changed

+37
-28
lines changed

UnityPy/environment.py

Lines changed: 37 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@
22
import ntpath
33
import os
44
import re
5-
from typing import TYPE_CHECKING, Callable, Dict, List, Optional, Union
5+
from typing import TYPE_CHECKING, BinaryIO, Callable, Dict, List, Optional, Union, cast
66
from zipfile import ZipFile
77

88
from fsspec import AbstractFileSystem
99
from fsspec.implementations.local import LocalFileSystem
1010

1111
from .enums import FileType
1212
from .files import BundleFile, File, ObjectReader, SerializedFile, WebFile
13+
from .helpers.ContainerHelper import ContainerHelper
1314
from .helpers.ImportHelper import (
1415
FileSourceType,
1516
check_file_type,
@@ -32,14 +33,22 @@ class Environment:
3233
local_files_simple: List[str]
3334
typetree_generator: Optional["TypeTreeGenerator"] = None
3435

35-
def __init__(self, *args: FileSourceType, fs: Optional[AbstractFileSystem] = None):
36+
def __init__(self, *args: FileSourceType, fs: Optional[AbstractFileSystem] = None, path: Optional[str] = None):
3637
self.files = {}
3738
self.cabs = {}
38-
self.path = None
3939
self.fs = fs or LocalFileSystem()
4040
self.local_files = []
4141
self.local_files_simple = []
4242

43+
if path is None:
44+
# if no path is given, use the current working directory
45+
if isinstance(self.fs, LocalFileSystem):
46+
self.path = os.getcwd()
47+
else:
48+
self.path = ""
49+
else:
50+
self.path = path
51+
4352
if args:
4453
for arg in args:
4554
if isinstance(arg, str):
@@ -56,15 +65,11 @@ def __init__(self, *args: FileSourceType, fs: Optional[AbstractFileSystem] = Non
5665
self.path = arg
5766
self.load_folder(arg)
5867
else:
59-
self.path = None
6068
self.load_file(file=arg)
6169

6270
if len(self.files) == 1:
6371
self.file = list(self.files.values())[0]
6472

65-
if self.path == "":
66-
self.path = os.getcwd()
67-
6873
def load_files(self, files: List[str]):
6974
"""Loads all files (list) into the Environment and merges .split files for common usage."""
7075
self.load_assets(files, lambda x: open(x, "rb"))
@@ -80,12 +85,12 @@ def load(self, files: List[str]):
8085
)
8186

8287
def _load_split_file(self, basename: str) -> bytes:
83-
file: list[str] = []
88+
file: List[bytes] = []
8489
for i in range(0, 999):
8590
item = f"{basename}.split{i}"
8691
if self.fs.exists(item):
8792
with self.fs.open(item, "rb") as f:
88-
file.append(f.read())
93+
file.append(f.read()) # type: ignore
8994
elif i:
9095
break
9196
return b"".join(file)
@@ -119,10 +124,13 @@ def load_file(
119124
# Unity paths are case insensitive,
120125
# so we need to find "Resources/Foo.asset" when the record says "resources/foo.asset"
121126
elif not os.path.exists(file):
122-
file = find_sensitive_path(self.path, file)
123-
# nonexistent files might be packaging errors or references to Unity's global Library/
124-
if file is None:
125-
return
127+
file_path = find_sensitive_path(self.path, file)
128+
if file_path:
129+
file = file_path
130+
else:
131+
return None
132+
# raise FileNotFoundError(f"File {file} not found in {self.path}")
133+
126134
if isinstance(file, str):
127135
file = self.fs.open(file, "rb")
128136

@@ -134,7 +142,7 @@ def load_file(
134142
else getattr(
135143
file,
136144
"name",
137-
str(file.__hash__()) if hasattr(file, "__hash__") else "",
145+
str(file.__hash__()) if hasattr(file, "__hash__") else "", # type: ignore
138146
)
139147
)
140148

@@ -150,16 +158,17 @@ def load_file(
150158
return f
151159

152160
def load_zip_file(self, value):
153-
buffer = None
154161
if isinstance(value, str) and self.fs.exists(value):
155-
buffer = open(value, "rb")
156-
elif isinstance(value, (bytes, bytearray)):
162+
buffer = cast(io.BufferedReader, self.fs.open(value, "rb"))
163+
elif isinstance(value, (bytes, bytearray, memoryview)):
157164
buffer = io.BytesIO(value)
158165
elif isinstance(value, (io.BufferedReader, io.BufferedIOBase)):
159166
buffer = value
167+
else:
168+
raise TypeError("Unsupported type for loading zip file")
160169

161170
z = ZipFile(buffer)
162-
self.load_assets(z.namelist(), lambda x: z.open(x, "r"))
171+
self.load_assets(z.namelist(), lambda x: z.open(x, "r")) # type: ignore
163172
z.close()
164173

165174
def save(self, pack="none", out_path="output"):
@@ -195,14 +204,14 @@ def search(item):
195204
return search(self)
196205

197206
@property
198-
def container(self) -> Dict[str, ObjectReader]:
207+
def container(self) -> ContainerHelper:
199208
"""Returns a dictionary of all objects in the Environment."""
200-
return {
201-
path: obj
202-
for f in self.files.values()
203-
if isinstance(f, File) and not f.is_dependency
204-
for path, obj in f.container.items()
205-
}
209+
container = []
210+
for f in self.cabs.values():
211+
if isinstance(f, SerializedFile) and not f.is_dependency:
212+
container.extend(f.container.container)
213+
214+
return ContainerHelper(container)
206215

207216
@property
208217
def assets(self) -> list:
@@ -228,7 +237,7 @@ def gen_all_asset_files(file, ret: Optional[list] = None):
228237
def get(self, key: str, default=None):
229238
return getattr(self, key, default)
230239

231-
def register_cab(self, name: str, item: File) -> None:
240+
def register_cab(self, name: str, item: Union[SerializedFile, EndianBinaryReader]) -> None:
232241
"""
233242
Registers a cab file.
234243
@@ -241,7 +250,7 @@ def register_cab(self, name: str, item: File) -> None:
241250
"""
242251
self.cabs[simplify_name(name)] = item
243252

244-
def get_cab(self, name: str) -> File:
253+
def get_cab(self, name: str) -> Union[SerializedFile, EndianBinaryReader, None]:
245254
"""
246255
Returns the cab file with the given name.
247256
@@ -257,7 +266,7 @@ def get_cab(self, name: str) -> File:
257266
"""
258267
return self.cabs.get(simplify_name(name), None)
259268

260-
def load_assets(self, assets: List[str], open_f: Callable[[str], io.IOBase]):
269+
def load_assets(self, assets: List[str], open_f: Callable[[str], BinaryIO]):
261270
"""
262271
Load all assets from a list of files via the given open_f function.
263272

0 commit comments

Comments
 (0)