Пример #1
0
 def do_info(self, **kwargs):
     """Add informational item to the minutes."""
     m = items.Info(**kwargs)
     self.additem(m)
Пример #2
0
    def __init__(self, map_path):
        # default list of item types
        for type_ in ITEM_TYPES:
            if type_ != 'version' and type_ != 'layer':
                setattr(self, ''.join([type_, 's']), [])

        path, filename = os.path.split(map_path)
        self.name, extension = os.path.splitext(filename)
        if extension == '':
            self.map_path = os.extsep.join([map_path, 'map'])
        elif extension != ''.join([os.extsep, 'map']):
            raise TypeError('Invalid file')
        else:
            self.map_path = map_path

        with open(self.map_path, 'rb') as f:
            self.f = f
            self.header = Header(f)
            self.item_types = []
            for i in range(self.header.num_item_types):
                val = unpack('3i', f.read(12))
                self.item_types.append({
                    'type': val[0],
                    'start': val[1],
                    'num': val[2],
                })
            fmt = '{0}i'.format(self.header.num_items)
            self.item_offsets = unpack(fmt, f.read(self.header.num_items * 4))
            fmt = '{0}i'.format(self.header.num_raw_data)
            self.data_offsets = unpack(fmt, f.read(self.header.num_raw_data * 4))

            # check version
            item_size, version_item = self.find_item(f, ITEM_VERSION, 0)
            fmt = '{0}i'.format(item_size/4)
            version = unpack(fmt, version_item)[0] # we only expect 1 element here
            if version != 1:
                raise ValueError('Wrong version')

            # load items
            # begin with map info
            item = self.find_item(f, ITEM_INFO, 0)
            if item is not None:
                item_size, item_data = item
                fmt = '{0}i'.format(item_size/4)
                item_data = unpack(fmt, item_data)
                version, author, map_version, credits, \
                license = item_data[:items.Info.type_size]
                if author > -1:
                    author = decompress(self.get_compressed_data(f, author))[:-1]
                else:
                    author = None
                if map_version > -1:
                    map_version = decompress(self.get_compressed_data(f, map_version))[:-1]
                else:
                    map_version = None
                if credits > -1:
                    credits = decompress(self.get_compressed_data(f, credits))[:-1]
                else:
                    credits = None
                if license > -1:
                    license = decompress(self.get_compressed_data(f, license))[:-1]
                else:
                    license = None
                self.info = items.Info(author=author, map_version=map_version,
                                       credits=credits, license=license)
            else:
                self.info = None

            # load images
            start, num = self.get_item_type(ITEM_IMAGE)
            for i in range(num):
                item = self.get_item(f, start+i)
                item_size, item_data = item
                fmt = '{0}i'.format(item_size/4)
                item_data = unpack(fmt, item_data)
                version, width, height, external, image_name, \
                image_data = item_data[:items.Image.type_size]
                external = bool(external)
                name = decompress(self.get_compressed_data(f, image_name))[:-1]
                data = decompress(self.get_compressed_data(f, image_data)) if not external else None
                image = items.Image(external=external, name=name,
                                   data=data, width=width, height=height)
                self.images.append(image)

            # load groups
            group_item_start, group_item_num = self.get_item_type(ITEM_GROUP)
            for i in range(group_item_num):
                item_size, item_data = self.get_item(f, group_item_start+i)
                fmt = '{0}i'.format(item_size/4)
                item_data = unpack(fmt, item_data)
                version, offset_x, offset_y, parallax_x, parallax_y, \
                start_layer, num_layers, use_clipping, clip_x, clip_y, \
                clip_w, clip_h = item_data[:items.Group.type_size-3]
                if version >= 3:
                    data = item_data[items.Group.type_size-3:items.Group.type_size]
                    group_name = ints_to_string(data) or None
                else:
                    group_name = None
                start_layer, num_layers = item_data[5:7]

                # load layers in group
                layer_item_start, layer_item_num = self.get_item_type(ITEM_LAYER)
                layers = []
                for j in range(num_layers):
                    item_size, item_data = self.get_item(f, layer_item_start+start_layer+j)
                    fmt = '{0}i'.format(item_size/4)
                    item_data = unpack(fmt, item_data)
                    layer_version, type_, flags = item_data[:items.Layer.type_size]
                    detail = True if flags else False

                    if type_ == LAYERTYPE_TILES:
                        type_size = items.TileLayer.type_size
                        color = 4*[0]
                        version, width, height, game, color[0], color[1], \
                        color[2], color[3], color_env, color_env_offset, \
                        image_id, data = item_data[3:type_size-3]
                        name = None
                        if version >= 3:
                            name = ints_to_string(item_data[type_size-3:type_size]) or None

                        tile_list = []
                        if game == 8: # Hack for front layer
                          if version >= 3:
                            tile_data = item_data[items.TileLayer.type_size+2]
                          else:
                            tile_data = item_data[items.TileLayer.type_size-1]
                          tile_data = decompress(self.get_compressed_data(f, tile_data))
                        else:
                          tile_data = decompress(self.get_compressed_data(f, data))
                        for i in xrange(0, len(tile_data), 4):
                          tile_list.append(tile_data[i:i+4])

                        tiles = items.TileManager(data=tile_list)
                        tele_tiles = None
                        speedup_tiles = None

                        if game == 2:
                            tele_list = []
                            if version >= 3:
                                # num of tele data is right after the default type length
                                if len(item_data) > items.TileLayer.type_size: # some security
                                    tele_data = item_data[items.TileLayer.type_size]
                                    if tele_data > -1 and tele_data < self.header.num_raw_data:
                                        tele_data = decompress(self.get_compressed_data(f, tele_data))
                                        for i in xrange(0, len(tele_data), 2):
                                            tele_list.append(tele_data[i:i+2])
                                        tele_tiles = items.TileManager(data=tele_list, _type=1)
                            else:
                                # num of tele data is right after num of data for old maps
                                if len(item_data) > items.TileLayer.type_size-3: # some security
                                    tele_data = item_data[items.TileLayer.type_size-3]
                                    if tele_data > -1 and tele_data < self.header.num_raw_data:
                                        tele_data = decompress(self.get_compressed_data(f, tele_data))
                                        for i in xrange(0, len(tele_data), 2):
                                            tele_list.append(tele_data[i:i+2])
                                        tele_tiles = items.TileManager(data=tele_list, _type=1)
                        elif game == 4:
                            speedup_list = []
                            if version >= 3:
                                # num of speedup data is right after tele data
                                if len(item_data) > items.TileLayer.type_size+1: # some security
                                    speedup_data = item_data[items.TileLayer.type_size+1]
                                    if speedup_data > -1 and speedup_data < self.header.num_raw_data:
                                        speedup_data = decompress(self.get_compressed_data(f, speedup_data))
                                        for i in xrange(0, len(speedup_data), 4):
                                            speedup_list.append(speedup_data[i:i+4])
                                        speedup_tiles = items.TileManager(data=speedup_list, _type=2)
                            else:
                                # num of speedup data is right after tele data
                                if len(item_data) > items.TileLayer.type_size-2: # some security
                                    speedup_data = item_data[items.TileLayer.type_size-2]
                                    if speedup_data > -1 and speedup_data < self.header.num_raw_data:
                                        speedup_data = decompress(self.get_compressed_data(f, speedup_data))
                                        for i in xrange(0, len(speedup_data), 4):
                                            speedup_list.append(speedup_data[i:i+4])
                                        speedup_tiles = items.TileManager(data=speedup_list, _type=2)
                        layer = items.TileLayer(width=width, height=height,
                                                name=name, detail=detail, game=game,
                                                color=tuple(color), color_env=color_env,
                                                color_env_offset=color_env_offset,
                                                image_id=image_id, tiles=tiles,
                                                tele_tiles=tele_tiles,
                                                speedup_tiles=speedup_tiles)
                        layers.append(layer)
                    elif type_ == LAYERTYPE_QUADS:
                        type_size = items.QuadLayer.type_size
                        version, num_quads, data, image_id = item_data[3:type_size-3]
                        name = None
                        if version >= 2:
                            name = ints_to_string(item_data[type_size-3:type_size]) or None
                        quad_data = decompress(self.get_compressed_data(f, data))
                        quad_list = []
                        for k in xrange(0, len(quad_data), 152):
                            quad_list.append(quad_data[k:k+152])
                        quads = items.QuadManager(data=quad_list)
                        layer = items.QuadLayer(name=name, detail=detail,
                                                image_id=image_id, quads=quads)
                        layers.append(layer)

                group = items.Group(name=group_name, offset_x=offset_x,
                                    offset_y=offset_y, parallax_x=parallax_x,
                                    parallax_y=parallax_y,
                                    use_clipping=use_clipping, clip_x=clip_x,
                                    clip_y=clip_y, clip_w=clip_w,
                                    clip_h=clip_h, layers=layers)
                self.groups.append(group)

            # load envpoints
            item_size, item = self.find_item(f, ITEM_ENVPOINT, 0)
            fmt = '{0}i'.format(item_size/4)
            item = unpack(fmt, item)
            type_size = items.Envpoint.type_size
            for i in range(len(item)/6):
                point = list(item[(i*6):(i*6+6)])
                time, curvetype = point[:type_size-4]
                values = point[type_size-4:type_size]
                envpoint = items.Envpoint(time=time, curvetype=curvetype,
                                          values=values)
                self.envpoints.append(envpoint)

            # load envelopes
            start, num = self.get_item_type(ITEM_ENVELOPE)
            type_size = items.Envelope.type_size
            for i in range(num):
                item_size, item_data = self.get_item(f, start+i)
                fmt = '{0}i'.format(item_size/4)
                item_data = unpack(fmt, item_data)
                version, channels, start_point, \
                num_point = item_data[:type_size-9]
                name = ints_to_string(item_data[type_size-9:type_size-1])
                envpoints = self.envpoints[start_point:start_point+num_point]
                synced = True if version < 2 or item_data[type_size-1] else False
                envelope = items.Envelope(name=name, version=version,
                                          channels=channels,
                                          envpoints=envpoints,
                                          synced=synced)
                self.envelopes.append(envelope)