HearthSim / UnityPack

Python deserialization library for Unity3D Asset format
https://hearthsim.info/
MIT License
720 stars 152 forks source link

Am I doing wrong? #23

Closed zhangbo closed 7 years ago

zhangbo commented 7 years ago

command: unityextract --all -o . sharedassets0.assets

Traceback (most recent call last):
  File "/usr/local/bin/unityextract", line 146, in <module>
    main()
  File "/usr/local/bin/unityextract", line 143, in main
    exit(app.run())
  File "/usr/local/bin/unityextract", line 49, in run
    self.handle_asset(asset)
  File "/usr/local/bin/unityextract", line 127, in handle_asset
    image = d.image
  File "/usr/local/lib/python3.6/site-packages/unitypack/engine/texture.py", line 165, in image
    data = bytes(self.image_data)
  File "/usr/local/lib/python3.6/site-packages/unitypack/engine/texture.py", line 137, in image_data
    if self.stream_data:
  File "/usr/local/lib/python3.6/site-packages/unitypack/engine/object.py", line 6, in _inner
    ret = self._obj[f]
KeyError: 'm_StreamData'

When I install unityPack with './setup.py install', I got this : command line : unityextract --all -o . resources.assets

Traceback (most recent call last):
  File "/usr/local/bin/unityextract", line 4, in <module>
    __import__('pkg_resources').run_script('unitypack==0.6.1', 'unityextract')
  File "/usr/local/lib/python3.6/site-packages/pkg_resources/__init__.py", line 739, in run_script
    self.require(requires)[0].run_script(script_name, ns)
  File "/usr/local/lib/python3.6/site-packages/pkg_resources/__init__.py", line 1494, in run_script
    exec(code, namespace, namespace)
  File "/usr/local/lib/python3.6/site-packages/unitypack-0.6.1-py3.6.egg/EGG-INFO/scripts/unityextract", line 146, in <module>
    main()
  File "/usr/local/lib/python3.6/site-packages/unitypack-0.6.1-py3.6.egg/EGG-INFO/scripts/unityextract", line 143, in main
    exit(app.run())
  File "/usr/local/lib/python3.6/site-packages/unitypack-0.6.1-py3.6.egg/EGG-INFO/scripts/unityextract", line 49, in run
    self.handle_asset(asset)
  File "/usr/local/lib/python3.6/site-packages/unitypack-0.6.1-py3.6.egg/EGG-INFO/scripts/unityextract", line 85, in handle_asset
    d = obj.read()
  File "/usr/local/lib/python3.6/site-packages/unitypack-0.6.1-py3.6.egg/unitypack/object.py", line 74, in read
    return self.read_value(self.type_tree, buf)
  File "/usr/local/lib/python3.6/site-packages/unitypack-0.6.1-py3.6.egg/unitypack/object.py", line 132, in read_value
    result[child.name] = self.read_value(child, buf)
  File "/usr/local/lib/python3.6/site-packages/unitypack-0.6.1-py3.6.egg/unitypack/object.py", line 100, in read_value
    size = buf.read_uint()
  File "/usr/local/lib/python3.6/site-packages/unitypack-0.6.1-py3.6.egg/unitypack/utils.py", line 107, in read_uint
    return struct.unpack(self.endian + "I", self.read(4))[0]
struct.error: unpack requires a bytes object of length 4
bobtekiMacBook-Pro:UnityPack bobsmith$ unityextract --all -o . /Applications/Army\ Truck\ 2\ -\ Civil\ Uprising\ 3D.app/Contents/Resources/Data/sharedassets0.assets
Traceback (most recent call last):
  File "/usr/local/bin/unityextract", line 4, in <module>
    __import__('pkg_resources').run_script('unitypack==0.6.1', 'unityextract')
  File "/usr/local/lib/python3.6/site-packages/pkg_resources/__init__.py", line 739, in run_script
    self.require(requires)[0].run_script(script_name, ns)
  File "/usr/local/lib/python3.6/site-packages/pkg_resources/__init__.py", line 1494, in run_script
    exec(code, namespace, namespace)
  File "/usr/local/lib/python3.6/site-packages/unitypack-0.6.1-py3.6.egg/EGG-INFO/scripts/unityextract", line 146, in <module>
    main()
  File "/usr/local/lib/python3.6/site-packages/unitypack-0.6.1-py3.6.egg/EGG-INFO/scripts/unityextract", line 143, in main
    exit(app.run())
  File "/usr/local/lib/python3.6/site-packages/unitypack-0.6.1-py3.6.egg/EGG-INFO/scripts/unityextract", line 49, in run
    self.handle_asset(asset)
  File "/usr/local/lib/python3.6/site-packages/unitypack-0.6.1-py3.6.egg/EGG-INFO/scripts/unityextract", line 85, in handle_asset
    d = obj.read()
  File "/usr/local/lib/python3.6/site-packages/unitypack-0.6.1-py3.6.egg/unitypack/object.py", line 74, in read
    return self.read_value(self.type_tree, buf)
  File "/usr/local/lib/python3.6/site-packages/unitypack-0.6.1-py3.6.egg/unitypack/object.py", line 132, in read_value
    result[child.name] = self.read_value(child, buf)
  File "/usr/local/lib/python3.6/site-packages/unitypack-0.6.1-py3.6.egg/unitypack/object.py", line 101, in read_value
    result = buf.read_string(size)
  File "/usr/local/lib/python3.6/site-packages/unitypack-0.6.1-py3.6.egg/unitypack/utils.py", line 72, in read_string
    ret = struct.unpack(self.endian + "%is" % (size), self.read(size))[0]
struct.error: unpack requires a bytes object of length 976121446
jleclanche commented 7 years ago

Can you upload the file you're trying to open?

vehumet commented 7 years ago

I'm not familiar to python syntax (such as * notation), so I'm just pasting my quick fix of this problem. I refered this url: http://stackoverflow.com/questions/5773607/python-what-is-the-most-efficient-way-to-generate-padding

In utils.py,

def read(self, *args):
  return self.buf.read(*args)

to this:

def read(self, args):
  readResult = self.buf.read(args)
  if (len(readResult) < args):
    readResult = readResult .ljust(args, b'\0')
  return readResult 

I omitted * of args for just make it run with least effort ;). Sorry for that. Sorry for not uploading problematic asset file, for it's confidential one.

Thank you.

jleclanche commented 7 years ago

That will prevent the crash but it won't actually help reading. All it's doing is feeding in garbage instead of feeding in nothing.

robert-nix commented 7 years ago

This was probably fixed by 11c22bc.

ghost commented 7 years ago

Sadly, error still occur: unityextract.py --all -o D:\TUM\UnityPack globalgamemanagers.assets output:

Traceback (most recent call last):
  File "%USERPROFILE%\AppData\Local\Programs\Python\Python36-32\Scripts\unityextract.py", line 153, in <module>
    main()
  File "%USERPROFILE%\AppData\Local\Programs\Python\Python36-32\Scripts\unityextract.py", line 149, in main
    exit(app.run())
  File "%USERPROFILE%\AppData\Local\Programs\Python\Python36-32\Scripts\unityextract.py", line 49, in run
    self.handle_asset(asset)
  File "%USERPROFILE%\AppData\Local\Programs\Python\Python36-32\Scripts\unityextract.py", line 91, in handle_asset
    d = obj.read()
  File "%USERPROFILE%\appdata\local\programs\python\python36-32\lib\site-packages\unitypack\object.py", line 74, in read
    return self.read_value(self.type_tree, buf)
  File "%USERPROFILE%\appdata\local\programs\python\python36-32\lib\site-packages\unitypack\object.py", line 132, in read_value
    result[child.name] = self.read_value(child, buf)
  File "%USERPROFILE%\appdata\local\programs\python\python36-32\lib\site-packages\unitypack\object.py", line 100, in read_value
    size = buf.read_uint()
  File "%USERPROFILE%\appdata\local\programs\python\python36-32\lib\site-packages\unitypack\utils.py", line 105, in read_uint
    return struct.unpack(self.endian + "I", self.read(4))[0]
struct.error: unpack requires a bytes object of length 4

Unity version: 5.4.0f3 Assets file in attachment: globalgamemanagers.zip

robert-nix commented 7 years ago

Your version of unitypack appears to be out of date; for example, this is the current object.py at line 132, whereas the traceback states result[child.name] = self.read_value(child, buf)