Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion UnityPy/environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,16 @@ def load_file(
file = b"".join(file)
else:
name = file
if not os.path.exists(file):
# relative paths are in the asset directory, not the cwd
if not os.path.isabs(file):
file = os.path.join(self.path, file)
# Unity paths are case insensitive, so we need to find "Resources/Foo.asset" when the record says "resources/foo.asset"
if not os.path.exists(file):
file = ImportHelper.find_sensitive_path(self.path, file)
# nonexistent files might be packaging errors or references to Unity's global Library/
if file is None:
return
file = self.fs.open(file, "rb")

typ, reader = ImportHelper.check_file_type(file)
Expand Down Expand Up @@ -155,7 +165,7 @@ def save(self, pack="none", out_path="output"):
for fname, fitem in self.files.items():
if getattr(fitem, "is_changed", False):
with open(
self.fs.sep.join([out_path, ntpath.basename(f)]), "wb"
self.fs.sep.join([out_path, ntpath.basename(fname)]), "wb"
) as out:
out.write(fitem.save(packer=pack))

Expand Down
22 changes: 20 additions & 2 deletions UnityPy/helpers/ImportHelper.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import os
from __future__ import annotations
import os
from typing import Union, List
from .CompressionHelper import BROTLI_MAGIC, GZIP_MAGIC
from ..enums import FileType
Expand Down Expand Up @@ -127,7 +128,7 @@ def parse_file(
name: str,
typ: FileType = None,
is_dependency=False,
):
) -> Union[files.File, EndianBinaryReader]:
if typ is None:
typ, _ = check_file_type(reader)
if typ == FileType.AssetsFile and not name.endswith(
Expand All @@ -141,3 +142,20 @@ def parse_file(
else:
f = reader
return f


def find_sensitive_path(dir: str, insensitive_path: str) -> Union[str, None]:
parts = os.path.split(insensitive_path.strip(os.path.sep))

senstive_path = dir
for part in parts:
part_lower = part.lower()
part = next(
(name for name in os.listdir(senstive_path) if name.lower() == part_lower),
None,
)
if next is None:
return None
senstive_path = os.path.join(senstive_path, part)

return senstive_path