Skip to content

Commit

Permalink
Handle relative and case insensitive file paths (#191)
Browse files Browse the repository at this point in the history
* Handle relative and case insensitive file paths

* improve find_sensitive_path (no recursion)

* environment.py - look in self.path instead of cwd

* fix files.File import error for type hinting

* Update environment.py

---------

Co-authored-by: Rudolf Kolbe <[email protected]>
  • Loading branch information
sparr and K0lb3 authored Sep 30, 2023
1 parent 63bfcc3 commit 289ec62
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 3 deletions.
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

0 comments on commit 289ec62

Please sign in to comment.