K0lb3 / UnityPy

UnityPy is python module that makes it possible to extract/unpack and edit Unity assets
MIT License
810 stars 123 forks source link

Add filter functionality to extractor #133

Closed sparr closed 2 years ago

sparr commented 2 years ago

This PR adds a new optional parameter to extract_assets and export_obj that will skip exporting objects based on a provided filter function.

Here is an example function from my real use case, which only exports audio clips over a certain length with names that match one of a list of file glob patterns and does not match any of another list of file glob patterns.

def asset_filter(obj):
    # Only export AudioClip assets
    if obj.type != ClassIDType.AudioClip:
        # incorrect type
        return False
    # A filter is called twice for each object
    # First, during extract_assets, when only metadata has been loaded
    # Second, during extract_obj, after the asset has been .read()
    # The checks here for m_Length and name will be skipped during the first pass
    if obj.m_Length is not None and obj.m_Length < args.minduration:
        # too short
        return False
    if obj.name is not None:
        for excludespec in assetsexcludespec:
            if excludespec and fnmatch.fnmatch(obj.name, excludespec):
                # excluded by an excludespec match
                return False
        for filespec in assetsfilespec:
            if filespec and fnmatch.fnmatch(obj.name, filespec):
                # included by a filespec match
                return True
        # not included by any filespec match
        return False
    # correct type, length and name checks skipped because they aren't available
    return True

The diff is a lot cleaner with whitespace changes omitted. https://github.com/K0lb3/UnityPy/pull/133/files?w=1