示例#1
0
文件: mubin.py 项目: NiceneNerd/BCML
def merge_dungeonstatic(diffs: dict = None):
    """Merges all changes to the CDungeon Static.smubin"""
    if not diffs:
        try:
            (util.get_master_modpack_dir() / "logs" /
             "dungeonstatic.smubin").unlink()
        except:
            pass
        return

    try:
        new_static = oead.byml.from_binary(
            util.decompress((util.get_aoc_dir() / "Map" / "CDungeon" /
                             "Static.smubin").read_bytes()))
    except FileNotFoundError:
        new_static = oead.byml.from_binary(
            util.get_nested_file_bytes(
                f"{util.get_game_file('Pack/Bootup.pack')}//Map/CDungeon/Static.smubin"
            ))

    base_names = [
        f"{str(spawn_point['Map'])}___{str(spawn_point['PosName'])}"
        for spawn_point in new_static["StartPos"]
    ]
    for spawn_name, diff in diffs.items():
        if "___" not in spawn_name:
            spawn_name = f"{spawn_name}___Entrance_1"
        if spawn_name not in base_names:
            new_static["StartPos"].append(diff)
        else:
            for key, value in diff.items():
                new_static["StartPos"][base_names.index(
                    spawn_name)][key] = value

    data = util.compress(
        oead.byml.to_binary(new_static, big_endian=util.get_settings("wiiu")))
    try:
        util.get_aoc_dir()
        output_static = (util.get_master_modpack_dir() / util.get_dlc_path() /
                         ("0010" if util.get_settings("wiiu") else "") /
                         "Map" / "CDungeon" / "Static.smubin")
    except FileNotFoundError:
        output_static = util.get_master_modpack_dir(
        ) / "logs" / "dungeonstatic.smubin"
        util.inject_file_into_sarc(
            "Map/CDungeon/Static.smubin",
            data,
            "Pack/Bootup.pack",
            create_sarc=True,
        )
    output_static.parent.mkdir(parents=True, exist_ok=True)
    output_static.write_bytes(data)
示例#2
0
def get_dungeonstatic_diff(mod_pos: Array) -> dict:
    try:
        base_pos = oead.byml.from_binary(
            util.decompress((util.get_aoc_dir() / "Map" / "CDungeon" /
                             "Static.smubin").read_bytes()))["StartPos"]
    except FileNotFoundError:
        base_pos = oead.byml.from_binary(
            util.get_nested_file_bytes(
                f"{util.get_game_file('Pack/Bootup.pack')}//Map/CDungeon/Static.smubin"
            ))["StartPos"]

    base_dungeons = [str(dungeon["Map"]) for dungeon in base_pos]
    diffs = {}
    for dungeon in mod_pos:
        if str(dungeon["Map"]) not in base_dungeons:
            diffs[dungeon["Map"]] = dungeon
        else:
            base_dungeon = base_pos[base_dungeons.index(str(dungeon["Map"]))]
            if dungeon["Rotate"] != base_dungeon["Rotate"]:
                diffs[dungeon["Map"]] = {"Rotate": dungeon["Rotate"]}
            if dungeon["Translate"] != base_dungeon["Translate"]:
                if dungeon["Map"] not in diffs:
                    diffs[dungeon["Map"]] = {}
                diffs[dungeon["Map"]]["Translate"] = dungeon["Translate"]

    return diffs
示例#3
0
def merge_dungeonstatic(diffs: dict = None):
    """Merges all changes to the CDungeon Static.smubin"""
    if not diffs:
        return

    new_static = oead.byml.from_binary(
        util.decompress((util.get_aoc_dir() / "Map" / "CDungeon" /
                         "Static.smubin").read_bytes()))

    base_dungeons = [str(dungeon["Map"]) for dungeon in new_static["StartPos"]]
    for dungeon, diff in diffs.items():
        if dungeon not in base_dungeons:
            new_static["StartPos"].append(diff)
        else:
            for key, value in diff.items():
                new_static["StartPos"][base_dungeons.index(
                    dungeon)][key] = value

    output_static = (util.get_master_modpack_dir() / util.get_dlc_path() /
                     ("0010" if util.get_settings("wiiu") else "") / "Map" /
                     "CDungeon" / "Static.smubin")
    output_static.parent.mkdir(parents=True, exist_ok=True)
    output_static.write_bytes(
        util.compress(
            oead.byml.to_binary(new_static,
                                big_endian=util.get_settings("wiiu"))))
示例#4
0
文件: mubin.py 项目: NiceneNerd/BCML
def get_dungeonstatic_diff(mod_pos: Array) -> dict:
    try:
        base_pos = oead.byml.from_binary(
            util.decompress((util.get_aoc_dir() / "Map" / "CDungeon" /
                             "Static.smubin").read_bytes()))["StartPos"]
    except FileNotFoundError:
        base_pos = oead.byml.from_binary(
            util.get_nested_file_bytes(
                f"{util.get_game_file('Pack/Bootup.pack')}//Map/CDungeon/Static.smubin"
            ))["StartPos"]

    base_names = [
        f"{str(spawn_point['Map'])}___{str(spawn_point['PosName'])}"
        for spawn_point in base_pos
    ]
    diffs = {}
    for mod_spawn in mod_pos:
        spawn_name = f"{str(mod_spawn['Map'])}___{str(mod_spawn['PosName'])}"
        if spawn_name not in base_names:
            diffs[spawn_name] = mod_spawn
        else:
            base_spawn = base_pos[base_names.index(spawn_name)]
            diff = {}
            if mod_spawn["Rotate"] != base_spawn["Rotate"]:
                diff["Rotate"] = mod_spawn["Rotate"]
            if mod_spawn["Translate"] != base_spawn["Translate"]:
                diff["Translate"] = mod_spawn["Translate"]
            if diff:
                diffs[spawn_name] = diff

    return diffs
示例#5
0
 def perform_merge(self):
     diffs = self.consolidate_diffs(self.get_all_diffs())
     output: Path
     static_data: Path
     try:
         util.get_aoc_dir()
         output = (util.get_master_modpack_dir() / util.get_dlc_path() /
                   ("0010" if util.get_settings("wiiu") else "") /
                   STATIC_PATH)
         static_data = util.get_game_file("Map/MainField/Static.smubin",
                                          aoc=True).read_bytes()
     except FileNotFoundError:
         output = util.get_master_modpack_dir(
         ) / "logs" / "mainstatic.smubin"
         static_data = util.get_nested_file_bytes(
             (str(util.get_game_file("Pack/Bootup.pack")) +
              "//Map/MainField/Static.smubin"),
             unyaz=False,
         )
     if not diffs:
         try:
             output.unlink()
         except:
             pass
         return
     stock_static = oead.byml.from_binary(util.decompress(static_data))
     merged = Hash()
     for cat in stock_static:
         if cat in diffs:
             items = {get_id(item): item for item in stock_static[cat]}
             util.dict_merge(items, diffs[cat])
             merged[cat] = Array([
                 item for _, item in items.items() if "remove" not in item
             ])
         else:
             merged[cat] = stock_static[cat]
     data = util.compress(
         oead.byml.to_binary(merged, big_endian=util.get_settings("wiiu")))
     output.parent.mkdir(parents=True, exist_ok=True)
     output.write_bytes(data)
     if "mainstatic" in str(output):
         util.inject_file_into_sarc(
             "Map/MainField/Static.smubin",
             data,
             "Pack/Bootup.pack",
             create_sarc=True,
         )
示例#6
0
def get_dungeonstatic_diff(file: Path) -> dict:
    base_pos = oead.byml.from_binary(
        util.decompress((util.get_aoc_dir() / "Map" / "CDungeon" /
                         "Static.smubin").read_bytes()))["StartPos"]

    mod_pos = oead.byml.from_binary(util.decompress(
        file.read_bytes()))["StartPos"]

    base_dungeons = [str(dungeon["Map"]) for dungeon in base_pos]
    diffs = {}
    for dungeon in mod_pos:
        if str(dungeon["Map"]) not in base_dungeons:
            diffs[dungeon["Map"]] = dungeon
        else:
            base_dungeon = base_pos[base_dungeons.index(str(dungeon["Map"]))]
            if dungeon["Rotate"] != base_dungeon["Rotate"]:
                diffs[dungeon["Map"]] = {"Rotate": dungeon["Rotate"]}
            if dungeon["Translate"] != base_dungeon["Translate"]:
                if dungeon["Map"] not in diffs:
                    diffs[dungeon["Map"]] = {}
                diffs[dungeon["Map"]]["Translate"] = dungeon["Translate"]

    return diffs
示例#7
0
 def is_bootup_injector():
     try:
         util.get_aoc_dir()
         return False
     except FileNotFoundError:
         return True
示例#8
0
def get_stock_map(map_unit: Union[Map, tuple],
                  force_vanilla: bool = False) -> Hash:
    if isinstance(map_unit, tuple):
        map_unit = Map(*map_unit)
    try:
        aoc_dir = util.get_aoc_dir()
    except FileNotFoundError:
        force_vanilla = True
    map_bytes = None
    map_path: Union[str, Path]
    if force_vanilla:
        try:
            if util.get_settings("wiiu"):
                update = util.get_update_dir()
            else:
                update = util.get_game_dir()
            map_path = (
                update / "Map/MainField/"
                f"{map_unit.section}/{map_unit.section}_{map_unit.type}.smubin"
            )
            if not map_path.exists():
                map_path = (
                    util.get_game_dir() / "Map/MainField/"
                    f"{map_unit.section}/{map_unit.section}_{map_unit.type}.smubin"
                )
            map_bytes = map_path.read_bytes()
        except FileNotFoundError:
            try:
                title_pack = oead.Sarc(
                    util.get_game_file("Pack/TitleBG.pack").read_bytes())
                map_bytes = title_pack.get_file(
                    f"Map/MainField/{map_unit.section}/{map_unit.section}_{map_unit.type}"
                    ".smubin").data
            except (KeyError, RuntimeError, AttributeError):
                map_bytes = None
    else:
        if (aoc_dir / "Pack" / "AocMainField.pack").exists():
            try:
                map_pack = oead.Sarc(
                    (aoc_dir / "Pack" / "AocMainField.pack").read_bytes())
                map_bytes = map_pack.get_file(
                    f"Map/MainField/{map_unit.section}/{map_unit.section}_{map_unit.type}"
                    ".smubin").data
            except (KeyError, RuntimeError, AttributeError):
                map_bytes = None
        if not map_bytes:
            map_path = f"Map/MainField/{map_unit.section}/{map_unit.section}_{map_unit.type}.smubin"
            try:
                map_bytes = util.get_game_file(map_path, aoc=True).read_bytes()
            except FileNotFoundError:
                try:
                    map_bytes = util.get_game_file(map_path).read_bytes()
                except FileNotFoundError:
                    try:
                        title_pack = oead.Sarc(
                            util.get_game_file(
                                "Pack/TitleBG.pack").read_bytes())
                        map_bytes = bytes(
                            title_pack.get_file(
                                f"Map/MainField/{map_unit.section}/"
                                f"{map_unit.section}_{map_unit.type}.smubin").
                            data)
                    except (KeyError, RuntimeError, AttributeError):
                        map_bytes = None
    if not map_bytes:
        raise FileNotFoundError(
            f"The stock map file {map_unit.section}_{map_unit.type}.smubin could not be found."
        )
    map_bytes = util.decompress(map_bytes)
    return oead.byml.from_binary(map_bytes)
示例#9
0
def get_stock_map(map_unit: Union[Map, tuple],
                  force_vanilla: bool = False) -> dict:
    """
    Finds the most significant available map unit from the unmodded game and returns its
    contents as a dict.

    :param map: The map section and type.
    :type map: class:`bcml.mubin.Map`
    :return: Returns a dict representation of the requested map unit.
    :rtype: dict
    """
    if isinstance(map_unit, tuple):
        map_unit = Map(*map_unit)
    try:
        aoc_dir = util.get_aoc_dir()
    except FileNotFoundError:
        force_vanilla = True
    map_bytes = None
    if force_vanilla:
        try:
            map_path = (
                util.get_update_dir() / 'Map/MainField/'
                f'{map_unit.section}/{map_unit.section}_{map_unit.type}.smubin'
            )
            if not map_path.exists():
                map_path = (
                    util.get_game_dir() / 'Map/MainField/'
                    f'{map_unit.section}/{map_unit.section}_{map_unit.type}.smubin'
                )
            map_bytes = map_path.read_bytes()
        except FileNotFoundError:
            with util.get_game_file('Pack/TitleBG.pack').open('rb') \
                  as s_file:
                title_pack = sarc.read_file_and_make_sarc(s_file)
            if title_pack:
                try:
                    map_bytes = title_pack.get_file_data(
                        f'Map/MainField/{map_unit.section}/{map_unit.section}_{map_unit.type}'
                        '.smubin').tobytes()
                except KeyError:
                    map_bytes = None
    else:
        if (aoc_dir / 'Pack' / 'AocMainField.pack').exists():
            with (aoc_dir / 'Pack' / 'AocMainField.pack').open('rb') as s_file:
                map_pack = sarc.read_file_and_make_sarc(s_file)
            if map_pack:
                try:
                    map_bytes = map_pack.get_file_data(
                        f'Map/MainField/{map_unit.section}/{map_unit.section}_{map_unit.type}'
                        '.smubin').tobytes()
                except KeyError:
                    map_bytes = None
        if not map_bytes:
            map_path = f'Map/MainField/{map_unit.section}/{map_unit.section}_{map_unit.type}.smubin'
            try:
                map_bytes = util.get_game_file(map_path, aoc=True).read_bytes()
            except FileNotFoundError:
                try:
                    map_bytes = util.get_game_file(map_path).read_bytes()
                except FileNotFoundError:
                    with util.get_game_file('Pack/TitleBG.pack').open('rb') \
                        as s_file:
                        title_pack = sarc.read_file_and_make_sarc(s_file)
                    if title_pack:
                        try:
                            map_bytes = title_pack.get_file_data(
                                f'Map/MainField/{map_unit.section}/'
                                f'{map_unit.section}_{map_unit.type}.smubin'
                            ).tobytes()
                        except KeyError:
                            map_bytes = None
    if not map_bytes:
        raise FileNotFoundError(
            f'The stock map file {map_unit.section}_{map_unit.type}.smubin could not be found.'
        )
    map_bytes = util.decompress(map_bytes)
    return byml.Byml(map_bytes).parse()