Example #1
0
def addFileToLayout(arc, folderName, name, data):
    fileAdded = False
    for folder in arc.contents:
        if isinstance(folder, SarcLib.Folder) and folder.name == "lyt_root":
            for lytFolder in folder.contents:
                if isinstance(lytFolder,
                              SarcLib.Folder) and lytFolder.name == folderName:
                    for file in lytFolder.contents:
                        if isinstance(file,
                                      SarcLib.File) and file.name == name:
                            lytFolder.removeFile(file)
                            break

                    file = SarcLib.File()
                    file.name = name
                    file.data = data

                    lytFolder.addFile(file)
                    fileAdded = True

                if fileAdded:
                    break

        if fileAdded:
            break

    if fileAdded:
        print("Added: %s" % name)

    else:
        print("Something went wrong while adding %s!" % name)

    return arc
Example #2
0
        def save(self):
            """
            Save the level back to a file
            """

            # Make a new archive
            newArchive = SarcLib.SARC_Archive()

            # Create a folder within the archive
            courseFolder = SarcLib.Folder('course')
            newArchive.addFolder(courseFolder)

            outerArchive = SarcLib.SARC_Archive()

            # Go through the areas, save them and add them back to the archive
            for areanum, area in enumerate(self.areas):
                course, L0, L1, L2 = area.save()

                if course is not None:
                    courseFolder.addFile(SarcLib.File('course%d.bin' % (areanum + 1), course))
                if L0 is not None:
                    courseFolder.addFile(SarcLib.File('course%d_bgdatL0.bin' % (areanum + 1), L0))
                if L1 is not None:
                    courseFolder.addFile(SarcLib.File('course%d_bgdatL1.bin' % (areanum + 1), L1))
                if L2 is not None:
                    courseFolder.addFile(SarcLib.File('course%d_bgdatL2.bin' % (areanum + 1), L2))

                # I need to kick in tileset saving here
                if area.tileset0 and area.tileset0Obj and not exists(outerArchive, area.tileset0):
                    outerArchive.addFile(SarcLib.File(area.tileset0, SaveTileset(area.tileset0, area.tileset0Obj)))

                if area.tileset1 and area.tileset1Obj and not exists(outerArchive, area.tileset1):
                    outerArchive.addFile(SarcLib.File(area.tileset1, SaveTileset(area.tileset1, area.tileset1Obj)))

                if area.tileset2 and area.tileset2Obj and not exists(outerArchive, area.tileset2):
                    outerArchive.addFile(SarcLib.File(area.tileset2, SaveTileset(area.tileset2, area.tileset2Obj)))

                if area.tileset3 and area.tileset3Obj and not exists(outerArchive, area.tileset3):
                    outerArchive.addFile(SarcLib.File(area.tileset3, SaveTileset(area.tileset3, area.tileset3Obj)))

            outerArchive.addFile(SarcLib.File(self.name, newArchive.save()[0]))

            return outerArchive.save()[0]
Example #3
0
    def save(self):
        arc = SarcLib.SARC_Archive()
        self.addSpriteFiles()

        # Look up every tileset used in each area
        tilesets_names = []
        for area_SARC in self.areas:
            if area_SARC.tileset0 not in ('', None):
                tilesets_names.append(area_SARC.tileset0)

            if area_SARC.tileset1 not in ('', None):
                tilesets_names.append(area_SARC.tileset1)

            if area_SARC.tileset2 not in ('', None):
                tilesets_names.append(area_SARC.tileset2)

            if area_SARC.tileset3 not in ('', None):
                tilesets_names.append(area_SARC.tileset3)

        tilesets_names = tuple(set(tilesets_names))

        # Add each tileset to our archive
        for tileset_name in tilesets_names:
            if tileset_name not in self.szsData:
                if os.path.isfile(
                        os.path.join(globals.mod_path,
                                     'Stage/Texture/%s.szs' % tileset_name)):
                    with open(
                            os.path.join(globals.mod_path,
                                         'Stage/Texture/%s.szs' %
                                         tileset_name), "rb") as inf:
                        self.szsData[tileset_name] = DecompYaz0(inf.read())

                else:
                    print("Tileset %s not found!" % tileset_name)

        for file in self.szsData:
            arc.addFile(SarcLib.File(file, self.szsData[file]))

        return arc.save()[0]
Example #4
0
        def save(self):
            """
            Save the level back to a file
            """

            # Make a new archive
            newArchive = SarcLib.SARC_Archive()

            # Create a folder within the archive
            courseFolder = SarcLib.Folder('course')
            newArchive.addFolder(courseFolder)

            # Go through the areas, save them and add them back to the archive
            for areanum, area in enumerate(self.areas):
                course, L0, L1, L2 = area.save()

                if course is not None:
                    courseFolder.addFile(
                        SarcLib.File('course%d.bin' % (areanum + 1), course))
                if L0 is not None:
                    courseFolder.addFile(
                        SarcLib.File('course%d_bgdatL0.bin' % (areanum + 1),
                                     L0))
                if L1 is not None:
                    courseFolder.addFile(
                        SarcLib.File('course%d_bgdatL1.bin' % (areanum + 1),
                                     L1))
                if L2 is not None:
                    courseFolder.addFile(
                        SarcLib.File('course%d_bgdatL2.bin' % (areanum + 1),
                                     L2))

            outerArchive = SarcLib.SARC_Archive()
            outerArchive.addFile(SarcLib.File('level', newArchive.save()[0]))
            outerArchive.addFile(SarcLib.File('levelname', b'level'))

            return outerArchive.save()[0]
Example #5
0
def pack(root, endianness, level, outname):
    """
    Pack the files and folders in the root folder.
    """

    if "\\" in root:
        root = "/".join(root.split("\\"))

    if root[-1] == "/":
        root = root[:-1]

    arc = SarcLib.SARC_Archive(endianness=endianness)
    lenroot = len(root.split("/"))

    for path, dirs, files in os.walk(root):
        if "\\" in path:
            path = "/".join(path.split("\\"))

        lenpath = len(path.split("/"))

        if lenpath == lenroot:
            path = ""

        else:
            path = "/".join(path.split("/")[lenroot - lenpath:])

        for file in files:
            if path:
                filename = ''.join([path, "/", file])

            else:
                filename = file

            print(filename)

            fullname = ''.join([root, "/", filename])

            i = 0
            for folder in filename.split("/")[:-1]:
                if not i:
                    exec(
                        "folder%i = SarcLib.Folder(folder + '/'); arc.addFolder(folder%i)"
                        .replace('%i', str(i)))

                else:
                    exec(
                        "folder%i = SarcLib.Folder(folder + '/'); folder%m.addFolder(folder%i)"
                        .replace('%i', str(i)).replace('%m', str(i - 1)))

                i += 1

            with open(fullname, "rb") as f:
                inb = f.read()

            hasFilename = True
            if file[:5] == "hash_":
                hasFilename = False

            if not i:
                arc.addFile(SarcLib.File(file, inb, hasFilename))

            else:
                exec("folder%m.addFile(SarcLib.File(file, inb, hasFilename))".
                     replace('%m', str(i - 1)))

    data, maxAlignment = arc.save()

    if level != -1:
        outData = libyaz0.compress(data, maxAlignment, level)
        del data

        if not outname:
            outname = ''.join([root, ".szs"])

    else:
        outData = data
        if not outname:
            outname = ''.join([root, ".sarc"])

    with open(outname, "wb+") as output:
        output.write(outData)
Example #6
0
    def saveNewArea(self, innerfilename, course_new, L0_new, L1_new, L2_new):
        """
        Save the level back to a file (when adding a new or deleting an existing Area)
        """

        # Make a new archive
        newArchive = SarcLib.SARC_Archive()

        # Create a folder within the archive
        courseFolder = SarcLib.Folder('course')
        newArchive.addFolder(courseFolder)

        # Go through the areas, save them and add them back to the archive
        for areanum, area in enumerate(self.areas):
            course, L0, L1, L2 = area.save(True)

            if course is not None:
                courseFolder.addFile(
                    SarcLib.File('course%d.bin' % (areanum + 1), course))
            if L0 is not None:
                courseFolder.addFile(
                    SarcLib.File('course%d_bgdatL0.bin' % (areanum + 1), L0))
            if L1 is not None:
                courseFolder.addFile(
                    SarcLib.File('course%d_bgdatL1.bin' % (areanum + 1), L1))
            if L2 is not None:
                courseFolder.addFile(
                    SarcLib.File('course%d_bgdatL2.bin' % (areanum + 1), L2))

        if course_new is not None:
            courseFolder.addFile(
                SarcLib.File('course%d.bin' % (len(self.areas) + 1),
                             course_new))
        if L0_new is not None:
            courseFolder.addFile(
                SarcLib.File('course%d_bgdatL0.bin' % (len(self.areas) + 1),
                             L0_new))
        if L1_new is not None:
            courseFolder.addFile(
                SarcLib.File('course%d_bgdatL1.bin' % (len(self.areas) + 1),
                             L1_new))
        if L2_new is not None:
            courseFolder.addFile(
                SarcLib.File('course%d_bgdatL2.bin' % (len(self.areas) + 1),
                             L2_new))

        # Here we have the new inner-SARC savedata
        innersarc = newArchive.save()[0]

        # Now make an outer SARC
        outerArchive = SarcLib.SARC_Archive()

        # Add the innersarc to it
        outerArchive.addFile(SarcLib.File(innerfilename, innersarc))

        # Make it easy for future Miyamotos to pick out the innersarc level name
        outerArchive.addFile(
            SarcLib.File('levelname', innerfilename.encode('utf-8')))

        # Add all the other stuff, too
        for szsThingName in globals.szsData:
            if szsThingName in [globals.levelNameCache, 'levelname']: continue
            outerArchive.addFile(
                SarcLib.File(szsThingName, globals.szsData[szsThingName]))

        # Save the outer sarc and return it
        return outerArchive.save()[0]
Example #7
0
    def save(self, innerfilename):
        """
        Save the level back to a file
        """

        # Make a new archive
        newArchive = SarcLib.SARC_Archive()

        # Create a folder within the archive
        courseFolder = SarcLib.Folder('course')
        newArchive.addFolder(courseFolder)

        # Go through the areas, save them and add them back to the archive
        for areanum, area in enumerate(self.areas):
            course, L0, L1, L2 = area.save()

            if course is not None:
                courseFolder.addFile(
                    SarcLib.File('course%d.bin' % (areanum + 1), course))
            if L0 is not None:
                courseFolder.addFile(
                    SarcLib.File('course%d_bgdatL0.bin' % (areanum + 1), L0))
            if L1 is not None:
                courseFolder.addFile(
                    SarcLib.File('course%d_bgdatL1.bin' % (areanum + 1), L1))
            if L2 is not None:
                courseFolder.addFile(
                    SarcLib.File('course%d_bgdatL2.bin' % (areanum + 1), L2))

        # Here we have the new inner-SARC savedata
        innersarc = newArchive.save()[0]
        globals.szsData[innerfilename] = innersarc

        # Now make an outer SARC
        outerArchive = SarcLib.SARC_Archive()

        # Add the innersarc to it
        outerArchive.addFile(SarcLib.File(innerfilename, innersarc))

        # Make it easy for future Miyamotos to pick out the innersarc level name
        outerArchive.addFile(
            SarcLib.File('levelname', innerfilename.encode('utf-8')))
        globals.szsData['levelname'] = innerfilename.encode('utf-8')

        # Save all the tilesets
        if globals.TilesetEdited or globals.OverrideTilesetSaving:
            if globals.Area.tileset1:
                tilesetData = SaveTileset(1)
                if tilesetData:
                    globals.szsData[globals.Area.tileset1] = tilesetData

            if globals.Area.tileset2:
                tilesetData = SaveTileset(2)
                if tilesetData:
                    globals.szsData[globals.Area.tileset2] = tilesetData

            if globals.Area.tileset3:
                tilesetData = SaveTileset(3)
                if tilesetData:
                    globals.szsData[globals.Area.tileset3] = tilesetData

        # Add all the other stuff, too
        if os.path.isdir(globals.miyamoto_path + '/data'):
            szsNewData = {}

            szsNewData[innerfilename] = innersarc
            szsNewData['levelname'] = innerfilename.encode('utf-8')

            paths = [
                globals.miyamoto_path + '/miyamotodata/spriteresources.xml'
            ]
            for path in globals.gamedef.recursiveFiles('spriteresources'):
                if path:
                    paths.append(
                        os.path.join(
                            globals.miyamoto_path,
                            path if isinstance(path, str) else path.path))

            sprites_xml = {}
            for path in paths:
                # Read the sprites resources xml
                tree = etree.parse(path)
                root = tree.getroot()

                # Get all sprites' filenames and add them to a list
                for sprite in root.iter('sprite'):
                    id = int(sprite.get('id'))

                    name = []
                    for id2 in sprite:
                        name.append(id2.get('name'))

                    sprites_xml[id] = list(name)

            # Look up every sprite and tileset used in each area
            sprites_SARC = []
            tilesets_names = []
            for area_SARC in globals.Level.areas:
                for sprite in area_SARC.sprites:
                    sprites_SARC.append(sprite.type)

                if area_SARC.tileset0 not in ('', None):
                    tilesets_names.append(area_SARC.tileset0)

                if area_SARC.tileset1 not in ('', None):
                    tilesets_names.append(area_SARC.tileset1)

                if area_SARC.tileset2 not in ('', None):
                    tilesets_names.append(area_SARC.tileset2)

                if area_SARC.tileset3 not in ('', None):
                    tilesets_names.append(area_SARC.tileset3)

            sprites_SARC = list(set(sprites_SARC))
            tilesets_names = list(set(tilesets_names))

            # Sort the filenames for each "used" sprite
            sprites_names = []
            for sprite in sprites_SARC:
                if sprite in sprites_xml:
                    for sprite_name in sprites_xml[sprite]:
                        sprites_names.append(sprite_name)

            sprites_names = list(set(sprites_names))

            # Look up each needed file and add it to our archive
            for sprite_name in sprites_names:
                # Get it from inside the original archive
                if not globals.OverwriteSprite and sprite_name in globals.szsData:
                    outerArchive.addFile(
                        SarcLib.File(sprite_name,
                                     globals.szsData[sprite_name]))
                    szsNewData[sprite_name] = globals.szsData[sprite_name]

                # Get it from the "custom" data folder
                elif os.path.isfile(globals.miyamoto_path + '/data/custom/' +
                                    sprite_name):
                    with open(
                            globals.miyamoto_path + '/data/custom/' +
                            sprite_name, 'rb') as f:
                        f1 = f.read()

                    outerArchive.addFile(SarcLib.File(sprite_name, f1))
                    szsNewData[sprite_name] = f1

                # Get it from the data folder
                elif os.path.isfile(globals.miyamoto_path + '/data/' +
                                    sprite_name):
                    with open(globals.miyamoto_path + '/data/' + sprite_name,
                              'rb') as f:
                        f1 = f.read()

                    outerArchive.addFile(SarcLib.File(sprite_name, f1))
                    szsNewData[sprite_name] = f1

                # Throw a warning because the file was not found...
                else:
                    print("WARNING: Could not find the file: %s" % sprite_name)
                    print("Expect the level to crash ingame...")

            # Add each tileset to our archive
            for tileset_name in tilesets_names:
                if tileset_name in globals.szsData:
                    outerArchive.addFile(
                        SarcLib.File(tileset_name,
                                     globals.szsData[tileset_name]))
                    szsNewData[tileset_name] = globals.szsData[tileset_name]

            globals.szsData = szsNewData

        else:
            # data folder not found, copy the files
            for szsThingName in globals.szsData:
                if szsThingName in [
                        globals.levelNameCache, innerfilename, 'levelname'
                ]:
                    continue
                outerArchive.addFile(
                    SarcLib.File(szsThingName, globals.szsData[szsThingName]))

        # Save the outer sarc and return it
        return outerArchive.save()[0]
Example #8
0
def SaveTileset(name, tilesetObj):
    """
    Saves a tileset from a specific slot
    """
    defs = tilesetObj.defs
    if defs is None:
        return False

    colldata = tilesetObj.colldata
    deffile = b''
    indexfile = b''

    for obj in defs:
        if obj is None:
            break

        indexfile += struct.pack('>HBBxB', len(deffile), obj.width, obj.height, obj.randByte)

        for row in obj.rows:
            for tile in row:
                if len(tile) == 3:
                    byte2 = tile[2] << 2
                    byte2 |= (tile[1] >> 8) & 3  # Slot

                    deffile += bytes([tile[0], tile[1] & 0xFF, byte2])

                else:
                    deffile += bytes(tile)

            deffile += b'\xFE'

        deffile += b'\xFF'

    arc = SarcLib.SARC_Archive()

    tex = SarcLib.Folder('BG_tex')
    arc.addFolder(tex)
    tex.addFile(SarcLib.File('%s.gtx' % name, writeGTX(*tilesetObj.img)))
    tex.addFile(SarcLib.File('%s_nml.gtx' % name, writeGTX(*tilesetObj.nml)))

    if tilesetObj.hatena_anime:
        tex.addFile(SarcLib.File('hatena_anime.gtx', writeGTX(*tilesetObj.hatena_anime)))

    if tilesetObj.block_anime:
        tex.addFile(SarcLib.File('block_anime.gtx', writeGTX(*tilesetObj.block_anime)))

    if tilesetObj.hatena_anime_L:
        tex.addFile(SarcLib.File('hatena_anime_L.gtx', writeGTX(*tilesetObj.hatena_anime_L)))

    if tilesetObj.block_anime_L:
        tex.addFile(SarcLib.File('block_anime_L.gtx', writeGTX(*tilesetObj.block_anime_L)))

    if tilesetObj.tuka_coin_anime:
        tex.addFile(SarcLib.File('tuka_coin_anime.gtx', writeGTX(*tilesetObj.tuka_coin_anime)))

    if tilesetObj.belt_conveyor_anime:
        tex.addFile(SarcLib.File('belt_conveyor_anime.gtx', writeGTX(*tilesetObj.belt_conveyor_anime)))

    chk = SarcLib.Folder('BG_chk')
    arc.addFolder(chk)
    chk.addFile(SarcLib.File('d_bgchk_%s.bin' % name, colldata))

    unt = SarcLib.Folder('BG_unt')
    arc.addFolder(unt)
    unt.addFile(SarcLib.File('%s.bin' % name, deffile))
    unt.addFile(SarcLib.File('%s_hd.bin' % name, indexfile))

    return arc.save()[0]
def change_water(path, water_type=0):
    water_types = [
        'Normal Water', 'Hot Water', 'Poison', 'Lava', 'Ice Water', 'Mud',
        'Clear Water', 'Sea Water'
    ]

    for parent_dir, dirs, files in os.walk(path):
        for file in files:
            current_path = '{0}{1}'.format(parent_dir, file)

            if 'water.extm.sstera' not in current_path:
                continue

            with open(current_path, 'rb') as infile:
                infile_binary = infile.read()

                while libyaz0.IsYazCompressed(infile_binary):
                    infile_binary = libyaz0.decompress(infile_binary)

                path, extension = os.path.splitext(current_path)
                filename = os.path.basename(current_path)

                if infile_binary[0x00:0x04] != b'SARC':
                    print('Not a sarc. :(')

                sarc = SarcLib.SARC_Archive()
                sarc.load(infile_binary)

                with tempfile.TemporaryDirectory() as temp_dir:
                    for sarc_file in sarc.contents:
                        if isinstance(sarc_file, SarcLib.File):
                            pos = 0
                            data = bytearray(sarc_file.data)
                            while pos + 8 <= len(sarc_file.data):
                                height, x_axis_flow_rate, z_axis_flow_rate, mate_check, mate = \
                                    struct.unpack('<3H2B', data[pos:pos + 0x08])

                                # height = 0x24cc
                                # x_axis_flow_rate = 0x8125
                                # z_axis_flow_rate = 0x8125
                                mate = water_type
                                mate_check = mate + 3

                                data[pos:pos + 0x08] = struct.pack(
                                    '<3H2B', height, x_axis_flow_rate,
                                    z_axis_flow_rate, mate_check, mate)

                                pos += 0x08

                            with open(
                                    '{0}/{1}'.format(temp_dir, sarc_file.name),
                                    'wb+') as outfile:
                                outfile.write(data)

                    sarc = SarcLib.SARC_Archive(endianness='>')

                    for path, dirs, files in os.walk(temp_dir):
                        for file in files:
                            with open('{0}/{1}'.format(path, file),
                                      'rb') as infile:
                                sarc.addFile(
                                    SarcLib.File(file, infile.read(), True))

                    data, alignment = sarc.save()
                    data = libyaz0.compress(data, alignment, 5)

                    destination = '{0}/output/MainField - {1}'.format(
                        os.path.dirname(__file__), water_types[water_type])

                    if not os.path.exists('{0}/output/'.format(
                            os.path.dirname(__file__))):
                        os.makedirs('{0}/output/'.format(
                            os.path.dirname(__file__)))
                    if not os.path.exists('{0}/output/MainField - {1}'.format(
                            os.path.dirname(__file__),
                            water_types[water_type])):
                        os.makedirs('{0}/output/MainField - {1}'.format(
                            os.path.dirname(__file__),
                            water_types[water_type]))

                    with open('{0}/{1}'.format(destination, filename),
                              'wb+') as outfile:
                        print('saving {0}...'.format(filename))
                        outfile.write(data)