K0lb3 / UnityPy

UnityPy is python module that makes it possible to extract/unpack and edit Unity assets

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Load dependencies with sensitive paths

abilun opened this issue · comments

Code
A snippet of the code section that cases the bug or error.

import os
import UnityPy

def unpack_all_assets(source_folder : str, destination_folder : str):
    # iterate over all files in source folder
    for root, dirs, files in os.walk(source_folder):
        for file_name in files:
            # generate file_path
            file_path = os.path.join(root, file_name)
            # load that file via UnityPy.load
            env = UnityPy.load(file_path)

            for obj in env.objects:
                # process specific object types
                if obj.type.name in ["Texture2D"]:
                    data = obj.read()
                    # create destination path
                    dest = os.path.join(destination_folder, data.name)
                    # make sure that the extension is correct
                    # you probably only want to do so with images/textures
                    dest, ext = os.path.splitext(dest)
                    dest = dest + ".png"

                    img = data.image
                    img.save(dest)


unpack_all_assets(source_folder='/home/dd/beat-saber/Beat Saber_Data', destination_folder='/tmp/exported_1')

Error
The error message that is produced by python.

Traceback (most recent call last):
  File "/home/dd/py/test.py", line 28, in <module>
    unpack_all_assets(source_folder='/home/dd/beat-saber/Beat Saber_Data', destination_folder='/tmp/exported_1')
  File "/home/dd/py/test.py", line 24, in unpack_all_assets
    img = data.image
          ^^^^^^^^^^
  File "/home/dd/.pyenv/versions/3.11.4/lib/python3.11/site-packages/UnityPy/classes/Texture2D.py", line 13, in image
    return Texture2DConverter.get_image_from_texture2d(self)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/dd/.pyenv/versions/3.11.4/lib/python3.11/site-packages/UnityPy/export/Texture2DConverter.py", line 101, in get_image_from_texture2d
    image_data = copy(bytes(texture_2d.image_data))
                            ^^^^^^^^^^^^^^^^^^^^^
  File "/home/dd/.pyenv/versions/3.11.4/lib/python3.11/site-packages/UnityPy/classes/Texture2D.py", line 51, in image_data
    self._image_data = get_resource_data(
                       ^^^^^^^^^^^^^^^^^^
  File "/home/dd/.pyenv/versions/3.11.4/lib/python3.11/site-packages/UnityPy/helpers/ResourceReader.py", line 38, in get_resource_data
    assets_file.load_dependencies(possible_names)
  File "/home/dd/.pyenv/versions/3.11.4/lib/python3.11/site-packages/UnityPy/files/SerializedFile.py", line 312, in load_dependencies
    self.environment.load_file(file_id.path, True)
  File "/home/dd/.pyenv/versions/3.11.4/lib/python3.11/site-packages/UnityPy/environment.py", line 116, in load_file
    file = ImportHelper.find_sensitive_path(self.path, file)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/dd/.pyenv/versions/3.11.4/lib/python3.11/site-packages/UnityPy/helpers/ImportHelper.py", line 159, in find_sensitive_path
    senstive_path = os.path.join(senstive_path, part)
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<frozen posixpath>", line 90, in join
  File "<frozen genericpath>", line 152, in _check_arg_types
TypeError: join() argument must be str, bytes, or os.PathLike object, not 'NoneType'

Bug
A description of what you expect to happen/see and what actually happens.

Expected to extract Textures, but having the stack trace above.
Caused by the recent merge of 191.
Previously was also struggling with relative filepaths like library/unity default assets. Updated to the most recent version of library.

To Reproduce

  • a copy of the file that causes the problem
❯ pip freeze | grep UnityPy
UnityPy==1.10.3
❯ python --version
Python 3.11.4
❯ uname -mro
6.5.5-arch1-1 x86_64 GNU/Linux

Also, if it helps:
Values' state I got with the debugger being at https://github.com/K0lb3/UnityPy/blame/master/UnityPy/helpers/ImportHelper.py#L147:

dir: '/home/dd/beat-saber/Beat Saber_Data'
insensitive_path: '/home/dd/beat-saber/Beat Saber_Data/Library/unity default resources'
parts: ('home/dd/beat-saber/Beat Saber_Data/Library', 'unity default resources')
part: None
part_lower: 'home/dd/beat-saber/beat saber_data/library'
senstive_path: '/home/dd/beat-saber-hack/beat-saber/Beat Saber_Data'

and there is no /home/dd/beat-saber/Beat Saber_Data/Library/unity default resources` dir as such.

Thanks for reporting the issue.
I knew that there was an issue with the function,
but I couldn't find it anymore and for some reason or another it somehow worked for my local test.

fixed by #212