Exemplo n.º 1
0
    def save(self, io=None):
        # load all file data.
        self.load_all()
        files = self._files

        if io is None:
            io = self._io

        # clean file.
        io.seek(0)
        io.truncate()

        head_data = b''

        # build head in memory.
        with BytesIO() as io_head:
            IOHelper.write_ascii_string(io_head, FILE_MAGIC)
            count = len(files)
            IOHelper.write_struct(io_head, 'i', count)

            # count file offset.
            # magic(16) + count(4) + info(264 * n) + hash(32)
            offset = 52 + count * 264

            for file in files:
                file['offset'] = offset
                file['size'] = len(file['data'])
                IOHelper.write_struct(io_head, '<2i', file['offset'],
                                      file['size'])
                if isinstance(file['name'], str):
                    name_data = file['name'].encode(encoding='euc_kr')
                elif isinstance(file['name'], bytes):
                    name_data = file['name']
                else:
                    raise Exception('Filename type Error: %s(%s)' %
                                    (file['name'], type(file['name'])))
                name = NPK._decrypt_name(name_data)
                io_head.write(name)

                offset += file['size']

            head_data = IOHelper.read_range(io_head)

        io.write(head_data)
        # write hash.
        io.write(
            hashlib.sha256(head_data[:len(head_data) // 17 * 17]).digest())

        for file in files:
            io.seek(file['offset'])
            io.write(file['data'])
Exemplo n.º 2
0
    def save(self, io=None):
        # load all file data.
        self.load_all()
        files = self._files

        if io is None:
            io = self._io

        # clean file.
        io.seek(0)
        io.truncate()

        # build head in memory.
        with BytesIO() as io_head:
            IOHelper.write_ascii_string(io_head, FILE_MAGIC)
            count = len(files)
            IOHelper.write_struct(io_head, 'i', count)

            # count file offset.
            # magic(16) + count(4) + info(264 * n) + hash(32)
            offset = 52 + count * 264

            for file in files:
                IOHelper.write_struct(io_head, '<2i', file['offset'],
                                      file['size'])
                name = NPK._decrypt_name(file['name'].encode(encoding='ascii'))
                io_head.write(name)

                offset += file['size']

            head_data = IOHelper.read_range(io_head)

        io.write(head_data)
        # write hash.
        io.write(
            hashlib.sha256(head_data[:len(head_data) // 17 * 17]).digest())

        for file in files:
            io.seek(file['offset'])
            io.write(file['data'])
Exemplo n.º 3
0
    def save(self, io=None):
        self.load_all()
        images = self._images
        color_board = self._color_board
        color_boards = self._color_boards
        map_images = self._map_images
        version = self._version

        images_data = []

        # compress data, get size, add to data_list.
        if version == FILE_VERSION_5:
            for map_image in sorted(map_images):
                data = map_image['data']
                map_image['raw_size'] = len(data)
                data = zlib.compress(data)
                map_image['data_size'] = len(data)

                images_data.append(data)
        else:
            for image in images:
                if image['format'] != IMAGE_FORMAT_LINK:
                    data = image['data']
                    if image['extra'] == IMAGE_EXTRA_ZLIB or image[
                            'extra'] == IMAGE_EXTRA_MAP_ZLIB:
                        data = zlib.compress(data)
                    image['size'] = len(data)

                    images_data.append(data)

        images_size = self._save_count_images_size()
        file_size = self._save_count_file_size(images_size, images_data)

        if io is None:
            io = self._io

        io.seek(0)
        io.truncate()

        with BytesIO() as io_head:
            if version == FILE_VERSION_1:
                IOHelper.write_ascii_string(io_head, FILE_MAGIC_OLD)
                # TODO: unknown, now be zero.
                IOHelper.write_struct(io_head, 'h', 0)
            else:
                # images_size
                IOHelper.write_ascii_string(io_head, FILE_MAGIC)
                IOHelper.write_struct(io_head, 'i', images_size)

            # keep, version, img_count
            IOHelper.write_struct(io_head, '<3i', 0, version, len(images))

            is_ver5 = version == FILE_VERSION_5

            if is_ver5:
                # map_count, file_size
                IOHelper.write_struct(io_head, '<2i', len(map_images),
                                      file_size)

            if version == FILE_VERSION_4 or is_ver5:
                # color_count
                IOHelper.write_struct(io_head, 'i', len(color_board))
                for color in color_board:
                    # color
                    IOHelper.write_struct(io_head, '<4B', *color)

            if is_ver5:
                for map_image in map_images:
                    IOHelper.write_struct(io_head, '<7i', map_image['keep'],
                                          map_image['format'],
                                          map_image['index'],
                                          map_image['data_size'],
                                          map_image['raw_size'],
                                          map_image['w'], map_image['h'])

            if version == FILE_VERSION_6:
                # color_board count.
                IOHelper.write_struct(io_head, 'i', len(color_boards))
                for color_board_v6 in color_boards:
                    # color_count
                    IOHelper.write_struct(io_head, 'i', len(color_board_v6))
                    for color in color_board_v6:
                        # color
                        IOHelper.write_struct(io_head, '<4B', *color)

            for image in images:
                # format
                IOHelper.write_struct(io_head, 'i', image['format'])
                if image['format'] == IMAGE_FORMAT_LINK:
                    # link
                    IOHelper.write_struct(io_head, 'i', image['link'])
                else:
                    # extra, w, h, size, x, y, mw, mh
                    IOHelper.write_struct(io_head, '<8i', image['extra'],
                                          image['w'], image['h'],
                                          image['size'], image['x'],
                                          image['y'], image['mw'], image['mh'])
                    if image['extra'] == IMAGE_EXTRA_MAP_ZLIB:
                        # keep_1, map_index, left, top, right, bottom, rotate
                        IOHelper.write_struct(io_head, '<7i', image['keep_1'],
                                              image['map_index'],
                                              image['left'], image['top'],
                                              image['right'], image['bottom'],
                                              image['rotate'])

            head_data = IOHelper.read_range(io_head)

        io.write(head_data)

        for data in images_data:
            io.write(data)