def extract_info(src):
    textures = {}
    cards = {}

    for root, dirs, files in os.walk(src):
        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)
            handle_asset(env, textures)

    # env = UnityPy.load(src)
    # handle_asset(env, textures)
    # handle_gameobject(env, cards)

    for root, dirs, files in os.walk(src):
        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)
            handle_gameobject(env, cards)

    return cards, textures
Exemple #2
0
def main():
    # load the original japanese localisation
    src = os.path.join(root, "522608825")
    e = UnityPy.load(src)
    # iterate over all localisation assets
    for cont, obj in e.container.items():
        # read the asset data
        data = obj.read()
        # get the localisation data
        script = json.loads(bytes(
            data.script))  # bytes wrapper to handle memoryview
        if hasattr(script, "infos"):
            continue
        print(data.name)
        # translate the localisation
        for entry in script["infos"]:
            entry["value"] = translate(entry["value"])
        # overwrite the original
        data.script = json.dumps(script, ensure_ascii=False,
                                 indent=4).encode("utf8")
        # apply the changes
        data.save()

    # save the modified Bundle as file
    with open(os.path.join(root, "522608825_patched"), "wb") as f:
        f.write(e.file.save())
Exemple #3
0
def processAsset(filePath):
    offset = {}
    indexTable = {}
    imageData = {}
    dataJson = {}

    baseName = os.path.basename(filePath)
    env = UnityPy.load(filePath)
    for obj in env.objects:
        data = obj.read()
        if str(data.type) == 'MonoBehaviour':
            tree = data.type_tree
            offset, indexTable = parseMono(tree)
        if str(data.type) == 'Texture2D':
            imageData[data.name] = data.image

    partsData = classifyFaceMouth(indexTable, baseName)

    dataJson['offset'] = offset
    dataJson['partsData'] = partsData

    os.makedirs(os.path.join(OUTPUT, baseName), exist_ok=True)

    with open(('%s\\%s\\data.json') % (OUTPUT, baseName), 'w',
              encoding='utf8') as f:
        json.dump(dataJson, f, indent=2, ensure_ascii=False)

    if baseName == '100007_01':
        imageData = loadNhaam(imageData)

    combineYCbCrA(imageData, baseName)
    for index in indexTable:
        combineYCbCrA(imageData, baseName, index, indexTable[index])
Exemple #4
0
 def load_files(self, assetfolder, assetnames):
     print("Loading assets..")
     paths = []
     for f in assetnames:
         paths.append(os.path.join(assetfolder, f))
     print(paths)
     self.env = UnityPy.load(*paths)
Exemple #5
0
def main():
    bf = Fake(
        signature="UnityFS",
        version=6,
        format=6,
        version_engine="2017.4.30f1",
        version_player="5.x.x",
        _class=BundleFile,
        files={},
    )
    # load default serialized file and prepare some variables for easier access to key objects
    env = UnityPy.load(SERIALIZED_PATH)
    sf = env.file  # serialized file
    or_bp = list(sf.objects.values())[0].__dict__  # object data

    bf.files["serialized_file"] = sf
    sf.flags = 4

    # remove all unnesessary stuff
    for key in list(sf.objects.keys()):
        del sf.objects[key]
    sf.externals = []

    # add all files from DATA_PATH
    for root, dirs, files in os.walk(DATA_PATH):
        for f in files:
            fp = os.path.join(root, f)
            if f[:3] == "CAB":
                add_cab(bf, sf, root, f)
            else:
                add_object(sf, fp, or_bp)

    # save edited bundle
    open("bundle_edited.unity3d", "wb").write(bf.save())
Exemple #6
0
def export_monobehaviours(asset_path: str, trees: dict):
    for r, d, fs in os.walk(asset_path):
        for f in fs:
            try:
                env = UnityPy.load(os.path.join(r, f))
            except:
                continue
            for obj in env.objects:
                if obj.type == "MonoBehaviour":
                    d = obj.read()
                    if obj.serialized_type.nodes:
                        tree = obj.read_typetree()
                    else:
                        if not d.m_Script:
                            continue
                            # RIP, no referenced script
                            # can only dump raw
                        script = d.m_Script.read()
                        # on-demand solution without already dumped tree
                        #nodes = generate_tree(
                        #    g, script.m_AssemblyName, script.m_ClassName, script.m_Namespace
                        #)
                        if script.m_ClassName not in trees:
                            # class not found in known trees,
                            # might have to add the classes of the other dlls
                            continue
                        nodes = FakeNode(**trees[script.m_ClassName])
                        tree = obj.read_typetree(nodes)
Exemple #7
0
def test_sprite():
    import UnityPy
    for f in os.listdir(SAMPLES):
        env = UnityPy.load(os.path.join(SAMPLES, f))
        for obj in env.objects:
            if obj.type == "Sprite":
                obj.read().image.save("test.png")
Exemple #8
0
def unpack(source_folder="arknights", destination_folder="arknights_extract"):
    import UnityPy

    for root, dirs, files in os.walk(source_folder):
        for file_name in files:
            file_path = os.path.join(root, file_name)
            env = UnityPy.load(file_path)
            for path, obj in env.container.items():
                dest = os.path.join(destination_folder, *path.split("/"))
                os.makedirs(os.path.dirname(dest), exist_ok=True)
                dest, ext = os.path.splitext(dest)

                if obj.type.name in ["Texture2D", "Sprite"]:
                    data = obj.read()
                    dest = dest + ".png"
                    data.image.save(dest)
                elif obj.type.name == "TextAsset":
                    data = obj.read()
                    dest = dest + ".txt"
                    with open(dest, "wb") as f:
                        f.write(bytes(data.script))
                elif obj.type.name == "MonoBehaviour":
                    if obj.serialized_type.nodes:
                        tree = obj.read_typetree()
                        dest = dest + ".json"
                        with open(dest, "wt", encoding="utf8") as f:
                            json.dump(tree, f, ensure_ascii=False, indent=4)
                    else:
                        data = obj.read()
                        dest = dest + ".bin"
                        with open(dest, "wb") as f:
                            f.write(data.raw_data)
Exemple #9
0
def test_audioclip():
    import UnityPy
    import platform
    env = UnityPy.load(os.path.join(SAMPLES, "char_118_yuki.ab"))
    for obj in env.objects:
        if obj.type == "AudioClip":
            clip = obj.read()
            assert (len(clip.samples) == 1)
Exemple #10
0
def test_texture2d():
    for f in os.listdir(SAMPLES):
        env = UnityPy.load(os.path.join(SAMPLES, f))
        for obj in env.objects:
            if obj.type == "Texture2D":
                data = obj.read()
                data.image.save("test.png")
                data.image = data.image.transpose(Image.ROTATE_90)
                data.save()
Exemple #11
0
def loadNhaam(imageData):
    # missing Nhaam's base Y file
    env = UnityPy.load(
        INPUT +
        '\\assets._gluonresources.images.emotion.story.chara.100007_01.parts\\100007_01_base_y'
    )
    for obj in env.objects:
        data = obj.read()
        if str(data.type) == 'Texture2D':
            imageData[data.name] = data.image
    return imageData
Exemple #12
0
def test_mesh():
    env = UnityPy.load(os.path.join(SAMPLES, "xinzexi_2_n_tex"))
    with open(os.path.join(SAMPLES, "xinzexi_2_n_tex_mesh"), "rb") as f:
        wanted = f.read().replace(b"\r", b"")
    for obj in env.objects:
        if obj.type == "Mesh":
            mesh = obj.read()
            data = mesh.export()
            if isinstance(data, str):
                data = data.encode("utf8").replace(b"\r", b"")
            assert data == wanted
def main():
    p = ArgumentParser()
    p.add_argument("src")
    args = p.parse_args(sys.argv[1:])
    for root, dirs, files in os.walk(args.src):
        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)
            extract_assets(env)
Exemple #14
0
def test_mesh():
    env = UnityPy.load(os.path.join(SAMPLES, "xinzexi_2_n_tex"))
    with open(os.path.join(SAMPLES, 'xinzexi_2_n_tex_mesh'), 'rb') as f:
        wanted = f.read().replace(b'\r', b'')
    for obj in env.objects:
        if obj.type == "Mesh":
            mesh = obj.read()
            data = mesh.export()
            if isinstance(data, str):
                data = data.encode('utf8').replace(b'\r', b'')
            assert data == wanted
Exemple #15
0
def extract_ref_objects(src):
    for root, dirs, files in os.walk(src):
        if len(nodes_to_parse) == local_state["total_handled"]:
            return
        for file_name in files:
            if len(nodes_to_parse) == local_state["total_handled"]:
                return
            # generate file_path
            file_path = os.path.join(root, file_name)
            # load that file via UnityPy.load
            env = UnityPy.load(file_path)
            handle_asset(env)
Exemple #16
0
def extract_info(src):
	audioClips = {}
	cards = {}

	for root, dirs, files in os.walk(src):
		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)
			handle_asset(env, audioClips, cards)

	for root, dirs, files in os.walk(src):
		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)
			handle_gameobject(env, audioClips, cards)

		# if ("card" in bundle.path or "initial_base" in bundle.path) and ("cardtexture" not in bundle.path):

	return cards
def extract_img_assets(db, dat_path, output_path, query, skip_existing):
    if not output_path.exists():
        os.makedirs(output_path)

    for name, size, h in db.execute(query):
        out_file_path = Path(output_path, name.split('/')[-1] + '.png')
        if skip_existing and out_file_path.exists():
            continue
        ab = UnityPy.load(Path(dat_path, h[:2], h).as_posix())
        for obj in ab.objects:
            if obj.type in [ClassIDType.Texture2D, ClassIDType.Sprite]:
                data = obj.read()
                img = data.image
                # TODO better filter
                if ('thumb' in data.name
                        or 'tex' in data.name) and img.width == img.height:
                    img = img.resize((int(img.width * 3 / 4), img.height))
                img.save(out_file_path)
Exemple #18
0
def extract_assets(src):
    # load source
    env = UnityPy.load(src)

    # iterate over assets
    for asset in env.assets:
        # assets without container / internal path will be ignored for now
        if not asset.container:
            continue
        # filter objects and put Texture2Ds at the end of the list
        objs = sorted(
            (obj for obj in asset.get_objects() if obj.type.name in TYPES),
            key=lambda x: 1 if x.type == "Texture2D" else 0)
        cobjs = sorted(((key, obj) for key, obj in asset.container.items()
                        if obj.type.name in TYPES),
                       key=lambda x: 1 if x[1].type == "Texture2D" else 0)
        # check which mode we will have to use
        num_cont = sum(cobjs)
        num_objs = len(objs)

        # check if container contains all important assets, if yes, just ignore the container
        if num_objs <= num_cont * 2:
            for asset_path, obj in cobjs:
                fp = os.path.join(DST,
                                  *asset_path.split('/')[IGNOR_DIR_COUNT:])
                export_obj(obj, fp)

        # otherwise use the container to generate a path for the normal objects
        else:
            extracted = []
            # find the most common path
            occurence_count = Counter(
                os.path.splitext(asset_path)[0]
                for asset_path in asset.container.keys())
            local_path = os.path.join(
                DST,
                *occurence_count.most_common(1)[0][0].split('/')
                [IGNOR_DIR_COUNT:])

            for obj in objs:
                if obj.path_id not in extracted:
                    extracted.extend(
                        export_obj(obj, local_path, append_name=True))
Exemple #19
0
def main():
    path = os.path.dirname(os.path.realpath(__file__))
    f = open(os.path.join(path, "asset_index"), "rb")
    index = read_asset_index(f)

    blocks = os.path.join(path, "blocks_export")
    ext = os.path.join(path, "export")

    for root, dirs, files in os.walk(blocks):
        for fp in files:
            env = UnityPy.load(os.path.join(root, fp))
            for ref, obj in env.container.items():
                if "/" in ref:
                    fp = os.path.join(ext, *ref.split("/"))
                else:
                    try:
                        fp = os.path.join(ext, *index[int(ref)].split("/"))
                    except KeyError:
                        print(ref)
                        continue

                if not export_object(obj, fp, False):
                    for obj in env.objects:
                        export_object(obj, fp, True)
Exemple #20
0
def fetch_segment_lines(segment: SegmentData):
    lines = []
    if segment.kind is SegmentKind.TEXT:
        story_id = str(segment.id).zfill(9)
        storyline_name = f'storytimeline_{story_id}'
        storytimeline_path = Path(DATA_ROOT, 'story/data', story_id[:2],
                                  story_id[2:6], storyline_name)
        env = UnityPy.load(storytimeline_path.as_posix())
        if not env.assets:
            raise FileNotFoundError(storytimeline_path)

        objects = {}
        timeline = None
        for obj in env.objects:
            if obj.type != ClassIDType.MonoBehaviour:
                continue

            if not timeline:
                obj_data = obj.read()
                if obj_data.name == storyline_name:
                    timeline = obj_data
                    continue

            objects[obj.path_id] = obj

        if not timeline:
            raise Exception(
                "storytimeline exists, but it's timeline is missing")

        for block in timeline.type_tree['BlockList']:
            for clip in block['TextTrack']['ClipList']:
                obj = objects[clip['m_PathID']]
                type_tree = obj.read().type_tree
                lines.append(LineData(type_tree['Name'], type_tree['Text']))

    return lines
def extract_assets(src):
    # load source
    env = UnityPy.load(src)

    # iterate over assets
    for asset in env.assets:
        # assets without container / internal path will be ignored for now
        if not asset.container:
            continue

        # check which mode we will have to use
        num_cont = sum(1 for obj in asset.container.values()
                       if obj.type in TYPES)
        num_objs = sum(1 for obj in asset.objects.values()
                       if obj.type in TYPES)

        # check if container contains all important assets, if yes, just ignore the container
        if num_objs <= num_cont * 2:
            for asset_path, obj in asset.container.items():
                fp = os.path.join(DST, *asset_path.split('/')
                                  [IGNOR_DIR_COUNT:])
                export_obj(obj, fp)

        # otherwise use the container to generate a path for the normal objects
        else:
            extracted = []
            # find the most common path
            occurence_count = Counter(os.path.splitext(asset_path)[
                                      0] for asset_path in asset.container.keys())
            local_path = os.path.join(
                DST, *occurence_count.most_common(1)[0][0].split('/')[IGNOR_DIR_COUNT:])

            for obj in asset.objects.values():
                if obj.path_id not in extracted:
                    extracted.extend(export_obj(
                        obj, local_path, append_name=True))
Exemple #22
0
def extract_assets(
    src: Union[Path, BytesIO, bytes, bytearray],
    dst: Path,
    use_container: bool = True,
    ignore_first_container_dirs: int = 0,
    append_path_id: bool = False,
    export_unknown_as_typetree: bool = False,
) -> List[int]:
    """Extracts all assets from the given source.

    Args:
        src (Union[Path, BytesIO, bytes, bytearray]): [description]
        dst (Path): [description]
        use_container (bool, optional): [description]. Defaults to True.
        ignore_first_container_dirs (int, optional): [description]. Defaults to 0.
        append_path_id (bool, optional): [description]. Defaults to False.
        export_unknown_as_typetree (bool, optional): [description]. Defaults to False.

    Returns:
        List[int]: [description]
    """
    # load source
    env = UnityPy.load(src)
    exported = []

    export_types_keys = list(EXPORT_TYPES.keys())

    def defaulted_export_index(type: ClassIDType):
        try:
            return export_types_keys.index(type)
        except IndexError:
            return 999

    if use_container:
        container = sorted(env.container,
                           lambda x: defaulted_export_index(x[1].type))
        for obj_path, obj in container:
            # the check of the various sub directories is required to avoid // in the path
            obj_dest = os.path.join(
                dst,
                *(x for x in obj_path.split("/")[:ignore_first_container_dirs]
                  if x),
            )
            os.makedirs(os.path.dirname(obj_dest), exist_ok=True)
            exported.extend(
                export_obj(
                    obj,
                    obj_dest,
                    append_path_id=append_path_id,
                    export_unknown_as_typetree=export_unknown_as_typetree,
                ))

    else:
        objects = sorted(env.objects, lambda x: defaulted_export_index(x.type))
        for obj in objects:
            if obj.path_id not in exported:
                exported.extend(
                    export_obj(
                        obj,
                        dst,
                        append_name=True,
                        append_path_id=append_path_id,
                        export_unknown_as_typetree=export_unknown_as_typetree,
                    ))

    return exported
        ms = info['FileVersionMS']
        ls = info['FileVersionLS']
        return HIWORD(ms), LOWORD(ms), HIWORD(ls), LOWORD(ls)
    except:
        print(
            '[ERROR:] Failed to fetch EFT Client version! Does getPath.py & config.ini exist in your installation folder?'
        )
        time.sleep(10)
        exit()
        return


if __name__ == "__main__":
    ClientVersion = ".".join(
        [str(i) for i in get_version_number(config['DEFAULT']['clientpath'])])
    UnityVersion = UnityPy.load(
        config['DEFAULT']['unitypath']).objects[0].assets_file.unity_version

cookies = {}
headers = {
    'User-Agent': 'UnityPlayer/' + str(UnityVersion) +
    ' (UnityWebRequest/1.0, libcurl/7.52.0-DEV)',
    'Content-Type': 'application/json',
    'App-Version': 'EFT Client ' + str(ClientVersion),
    'X-Unity-Version': str(UnityVersion)
}

print('                                                ▄')
print('                                              ╓▀▀▄')
print('              ╓▐▌▒█▒▌▀▀▄╖                   ╓▀▀▀▀╢')
print('            ┌▀▀▀▀▒█▌▄▄▐▄▀╠                ╓╢▀▀▀▀▀▀▄')
print('           ╒╓▄▄▄▌██▌▐▒█▌▄▄▄             ╓╢▀▀▀▀▀▀▀▀▀')
Exemple #24
0
def test_read_single():
    for f in os.listdir(SAMPLES):
        env = UnityPy.load(os.path.join(SAMPLES, f))
        for obj in env.objects:
            obj.read()
Exemple #25
0
def test_read_batch():
    env = UnityPy.load(SAMPLES)
    for obj in env.objects:
        obj.read()
Exemple #26
0
def test_read_typetree():
    env = UnityPy.load(SAMPLES)
    for obj in env.objects:
        obj.read_typetree()
Exemple #27
0
import os
import UnityPy
from UnityPy.classes import MonoBehaviour, PPtr


class ScriptableTexture2D(MonoBehaviour):
    def __init__(self, reader):
        # calls the default MonoBehaviour init
        super().__init__(reader=reader)
        # here goes the implementation of the extra data
        self.texture = PPtr(reader)


# set the path for the target file
root = os.path.dirname(os.path.realpath(__file__))
fp = os.path.join(root, "data.unity3d")

env = UnityPy.load(fp)

# find the correct asset
for obj in env.objects:
    if obj.type == "MonoBehaviour":
        data = obj.read()
        if data.name == "ScriptableTexture2D":
            # correct obj found
            # lets read it with the custom class
            st = ScriptableTexture2D(obj)
            # read the linked image and save it
            tex = st.texture.read()
            print(st.texture.read().name)
            #tex.image.save(os.path.join(root, f"{tex.name}.png"))
Exemple #28
0
import UnityPy

env = UnityPy.load('data_processing/input/signatureabilities',
                   'data_processing/input/localization')

for obj in env.objects:
    data = obj.read()
    if data.title == 'Char_Valentine_SUP_CombatClinic_Title':
        print(data.title)
        break

obj = env.container[
    'assets/characters/valentine/signatureabilities/resources/sa_valentine_sup_combatclinic.prefab']
data = obj.read()
tree = data.read_type_tree()
tree.to_dict()

env.assets['signatureabilities']
env.assets['signatureabilities']['CAB-33795db553e340f803b94491ed8d8bb8'].keys()
env.assets['signatureabilities']['CAB-33795db553e340f803b94491ed8d8bb8'][
    -4662963343376788019].read().read_type_tree().to_dict()
env.assets['signatureabilities']['CAB-33795db553e340f803b94491ed8d8bb8'][
    -9170200783047960356].read().read_type_tree().to_dict()
env.assets['signatureabilities'].keys()
env.objects

data = obj.read()
tree = data.read_type_tree()
tree.to_dict()

for obj in env.objects: