예제 #1
0
def decode_medal_times(data: bytes,
                       offset: int,
                       debug: bool = False) -> List[MedalTime]:
    """
    Must start with the length byte.

    :param data:
    :param offset:
    :param debug:
    """
    times = utils.unpack_from('<B', data, offset, ("checkpoint times", ),
                              debug)[0]
    offset += 1
    m_times = [MedalTime() for _ in range(times)]
    # we do not use iter_unpack because its easier to use the offset debugging
    for i in range(times):
        m_times[i].platin = utils.unpack_from('<I', data, offset,
                                              ("platin time", ), debug)[0]
        offset += 4

    for i in range(times):
        m_times[i].gold = utils.unpack_from('<I', data, offset,
                                            ("gold time", ), debug)[0]
        offset += 4

    for i in range(times):
        m_times[i].silver = utils.unpack_from('<I', data, offset,
                                              ("silver time", ), debug)[0]
        offset += 4

    for i in range(times):
        m_times[i].bronze = utils.unpack_from('<I', data, offset,
                                              ("bronze time", ), debug)[0]
        offset += 4
    return m_times
예제 #2
0
파일: entities.py 프로젝트: IceflowRE/cmt
    def decode(cls, data: bytes, offset: int, debug: bool = False) -> 'PlayerStart':
        ent = PlayerStart()

        utils.unpack_from('<B', data, offset, ("unused",), debug)
        offset += 1
        ent.position = utils.unpack_from('<ddd', data, offset, ("position x", "position y", "position z"), debug)
        offset += 3 * 8
        ent.rotation_z = utils.unpack_from('<f', data, offset, ("rotation z",), debug)[0]
        offset += 4
        return ent
예제 #3
0
파일: entities.py 프로젝트: IceflowRE/cmt
    def decode(cls, data: bytes, offset: int, debug: bool = False) -> 'Dummy':
        ent = Dummy()

        ent.id = utils.unpack_from('<B', data, offset, ("id",), debug)[0]
        offset += 1
        ent.position = utils.unpack_from('<ddd', data, offset, ("position x", "position y", "position z"), debug)
        offset += 3 * 4
        ent.scale = utils.unpack_from('<ddd', data, offset, ("scale x", "scale y", "scale z"), debug)
        offset += 3 * 4
        ent.rotation_z = utils.unpack_from('<f', data, offset, ("rotation z",), debug)[0]
        return ent
예제 #4
0
파일: entities.py 프로젝트: IceflowRE/cmt
    def decode(cls, data: bytes, offset: int, debug: bool = False) -> 'Block':
        ent = Block()

        ent.block_type = BlockType(utils.unpack_from('<B', data, offset, ("block type",), debug)[0])
        offset += 1
        ent.position = utils.unpack_from('<ddd', data, offset, ("position x", "position y", "position z"), debug)
        offset += 3 * 8
        ent.scale = utils.unpack_from('<ddd', data, offset, ("scale x", "scale y", "scale z"), debug)
        offset += 3 * 8
        ent.rotation_z = utils.unpack_from('<f', data, offset, ("rotation z",), debug)[0]
        offset += 4
        ent.checkpoint_nr = None
        if ent.block_type == BlockType.CHECKPOINT:
            ent.checkpoint_nr = utils.unpack_from('<B', data, offset, ("checkpoint nr",), debug)[0]
            ent.byte_size += 1
        return ent
예제 #5
0
    def decode(cls, data: bytes, offset: int, debug: bool = False):
        ent = Sphere()

        ent.position = utils.unpack_from(
            '<iiI', data, offset, ("position x", "position y", "position z"),
            debug)
        return ent
예제 #6
0
def decode(file: Path, debug: bool = False) -> AMap:
    """
    :raises ValueError: something failed
    """
    with file.open("rb") as reader:
        data = reader.read()

    identifier = data[0:11].decode("utf-8")
    if debug:
        utils.debug_print(data[0:11], "identifier", identifier, 0)
    offset = 11

    if identifier == MapType.CMAP.value:
        version = utils.unpack_from('<B', data, offset, ("version", ),
                                    debug)[0]
        offset += 1
        if version == 0:
            return CMap_0.decode(data, offset, debug)
        elif version == 1:
            return CMap_1.decode(data, offset, debug)
        else:
            raise ValueError(
                f"reading .cmap version {version} is not supported")
    elif identifier == MapType.ECMAP.value:
        version = utils.unpack_from('<B', data, offset, ("version", ),
                                    debug)[0]
        offset += 1
        if version == 0:
            return ECMap_0.decode(data, offset, debug)
        elif version == 1:
            return ECMap_1.decode(data, offset, debug)
        elif version == 2:
            return ECMap_2.decode(data, offset, debug)
        else:
            raise ValueError(
                f"reading .ecmap version {version} is not supported")
    else:
        raise ValueError("given data is not a .cmap or .ecmap")
예제 #7
0
파일: entities.py 프로젝트: IceflowRE/cmt
    def decode(cls, data: bytes, offset: int, debug: bool = False) -> 'BarrierFloor':
        ent = BarrierFloor()

        utils.unpack_from('<B', data, offset, ("unused",), debug)
        offset += 1
        ent.position = utils.unpack_from('<ddd', data, offset, ("position x", "position y", "position z"), debug)
        offset += 3 * 8
        ent.scale_x = utils.unpack_from('<d', data, offset, ("scale x",), debug)[0]
        offset += 8
        ent.scale_y = utils.unpack_from('<d', data, offset, ("scale y",), debug)[0]
        offset += 8
        ent.rotation_z = utils.unpack_from('<f', data, offset, ("rotation z",), debug)[0]
        return ent
예제 #8
0
def decode(file: Path, debug: bool = False) -> AMap:
    """
    :raises ValueError: something failed
    """
    with file.open("rb") as reader:
        data = reader.read()

    identifier = data[0:11].decode("utf-8")
    if debug:
        utils.debug_print(data[0:11], "identifier", identifier, 0)
    offset = 11

    if identifier != MapType.CMAP.value and identifier != MapType.ECMAP.value:
        raise ValueError("given data is not a .cmap or .ecmap")

    version = utils.unpack_from('<B', data, offset, ("version", ), debug)[0]
    offset += 1

    map_cls = _TYPE_MAP.get((MapType(identifier), version), None)
    if map_cls is None:
        raise ValueError(
            f"reading {identifier} version {version} is not supported")

    return map_cls.decode(data, offset, debug)
예제 #9
0
    def decode(cls, data: bytes, offset: int, debug: bool = False) -> CMap_2:
        cmap = CMap_2()

        name_len = utils.unpack_from('<B', data, offset, ("name length", ),
                                     debug)[0]
        offset += 1

        cmap.name = data[offset:offset + name_len].decode("utf-8")
        if debug:
            utils.debug_print(data[offset:offset + name_len], "name",
                              cmap.name, offset)
        offset += name_len

        utils.unpack_from('<?', data, offset, ("unused (gamemode)", ), debug)
        offset += 1

        cmap.sun_rotation_hor = utils.unpack_from(
            '<f', data, offset, ("sun rotation horizontal", ), debug)[0]
        offset += 4

        cmap.sun_rotation_ver = utils.unpack_from('<f', data, offset,
                                                  ("sun rotation vertical", ),
                                                  debug)[0]
        offset += 4

        cmap.camera_pos = utils.unpack_from(
            '<ddd', data, offset,
            ("camera pos x", "camera pos y", "camera pos z"), debug)
        offset += 3 * 8

        cmap.camera_look = utils.unpack_from(
            '<ddd', data, offset,
            ("camera look x", "camera look y", "camera look z"), debug)
        offset += 3 * 8

        # entities processing
        ent_count = utils.unpack_from('<I', data, offset, ("entity count", ),
                                      debug)[0]
        offset += 4

        ent_done = 0
        while ent_done < ent_count:
            ent_type = utils.unpack_from('<B', data, offset, ("entity type", ),
                                         debug)[0]
            offset += 1
            if ent_type == 0:
                cur_ent = Block_2.decode(data, offset, debug)
                cmap.entities.append(cur_ent)
                offset += cur_ent.byte_size
            elif ent_type == 1:
                cur_ent = Sphere_2.decode(data, offset, debug)
                cmap.entities.append(cur_ent)
                offset += cur_ent.byte_size
            elif ent_type == 2:
                cur_ent = PlayerStart_2.decode(data, offset, debug)
                cmap.entities.append(cur_ent)
                offset += cur_ent.byte_size
            elif ent_type == 3:
                cur_ent = BarrierWall_2.decode(data, offset, debug)
                cmap.entities.append(cur_ent)
                offset += cur_ent.byte_size
            elif ent_type == 4:
                cur_ent = BarrierFloor_2.decode(data, offset, debug)
                cmap.entities.append(cur_ent)
                offset += cur_ent.byte_size
            elif ent_type == 128:
                cur_ent = Dummy_2.decode(data, offset, debug)
                cmap.entities.append(cur_ent)
                offset += cur_ent.byte_size
            else:
                raise ValueError(
                    f"Unknown entity type: {ent_type} at {offset - 1}")
            ent_done += 1
        if debug:
            print(offset, " / ", len(data), " consumed")
        if offset != len(data):
            raise ValueError("Not all bytes were consumed")
        return cmap
예제 #10
0
파일: cmap.py 프로젝트: IceflowRE/cmt
    def decode(cls, data: bytes, offset: int, debug: bool = False) -> CMap:
        cmap = CMap()

        name_len = utils.unpack_from('<B', data, offset, ("name length",), debug)[0]
        offset += 1

        cmap.name = data[offset:offset + name_len].decode("utf-8")
        if debug:
            utils.debug_print(data[offset:offset + name_len], "name", cmap.name, offset)
        offset += name_len

        utils.unpack_from('<?', data, offset, ("unused (gamemode)",), debug)
        offset += 1

        # checkpoint times
        cmap.checkpoint_times = decode_checkpoint_times(data, offset, debug)
        # checkpoint times count + 4 (platin, gold, silver, bronze) * checkpoint times * 4 bytes
        offset += 1 + 4 * len(cmap.checkpoint_times) * 4

        cmap.sun_rotation = utils.unpack_from('<f', data, offset, ("sun rotation",), debug)[0]
        offset += 4

        cmap.sun_angle = utils.unpack_from('<f', data, offset, ("sun angle",), debug)[0]
        offset += 4

        cmap.camera_pos = utils.unpack_from('<ddd', data, offset, ("camera pos x", "camera pos y", "camera pos z"),
                                            debug)
        offset += 3 * 8

        cmap.camera_look = utils.unpack_from('<ddd', data, offset, ("camera look x", "camera look y", "camera look z"),
                                             debug)
        offset += 3 * 8

        # entities processing
        ent_count = utils.unpack_from('<I', data, offset, ("entity count",), debug)[0]
        offset += 4

        ent_done = 0
        while ent_done < ent_count:
            ent_type = utils.unpack_from('<B', data, offset, ("entity type",), debug)[0]
            offset += 1
            if ent_type == 0:
                cur_ent = Block.decode(data, offset, debug)
                cmap.entities.append(cur_ent)
                offset += cur_ent.byte_size
            elif ent_type == 1:
                cur_ent = Sphere.decode(data, offset, debug)
                cmap.entities.append(cur_ent)
                offset += cur_ent.byte_size
            elif ent_type == 2:
                cur_ent = PlayerStart.decode(data, offset, debug)
                cmap.entities.append(cur_ent)
                offset += cur_ent.byte_size
            elif ent_type == 128:
                cur_ent = Dummy.decode(data, offset, debug)
                cmap.entities.append(cur_ent)
                offset += cur_ent.byte_size
            else:
                raise ValueError(f"Unknown entity type: {ent_type} at {offset - 1}")
            ent_done += 1
        if debug:
            print(offset, " / ", len(data), " consumed")
        if offset != len(data):
            raise ValueError("Not all bytes were consumed")
        return cmap
예제 #11
0
파일: ecmap.py 프로젝트: IceflowRE/cmt
    def decode(cls, data: bytes, offset: int, debug: bool = False) -> 'ECMAP':
        cmap = CMap_0()

        name_len = utils.unpack_from('<B', data, offset, ("name length", ),
                                     debug)[0]
        offset += 1

        cmap.name = data[offset:offset + name_len].decode("utf-8")
        if debug:
            utils.debug_print(data[offset:offset + name_len], "name",
                              cmap.name, offset)
        offset += name_len

        cmap.timer_enabled = utils.unpack_from('<?', data, offset,
                                               ("timer enabled", ), debug)
        offset += 1
        utils.unpack_from('<B', data, offset, ("unused", ), debug)
        offset += 1

        cmap.sun_rotation = utils.unpack_from('<f', data, offset,
                                              ("sun rotation", ), debug)[0]
        offset += 4

        cmap.sun_angle = utils.unpack_from('<f', data, offset, ("sun angle", ),
                                           debug)[0]
        offset += 4

        cmap.camera_pos = utils.unpack_from(
            '<ddd', data, offset,
            ("camera pos x", "camera pos y", "camera pos z"), debug)
        offset += 3 * 8

        cmap.camera_look = utils.unpack_from(
            '<ddd', data, offset,
            ("camera look x", "camera look y", "camera look z"), debug)
        offset += 3 * 8

        # entities processing
        ent_count = utils.unpack_from('<I', data, offset, ("entity count", ),
                                      debug)[0]
        offset += 4

        ent_done = 0

        while ent_done < ent_count:
            ent_type = utils.unpack_from('<B', data, offset, ("entity type", ),
                                         debug)[0]
            offset += 1
            if ent_type == 0:
                cur_ent = Block_0.decode(data, offset, debug)
                cmap.entities.append(cur_ent)
                offset += cur_ent.byte_size
            elif ent_type == 1:
                cur_ent = Sphere_0.decode(data, offset, debug)
                cmap.entities.append(cur_ent)
                offset += cur_ent.byte_size
            elif ent_type == 2:
                cur_ent = PlayerStart_0.decode(data, offset, debug)
                cmap.entities.append(cur_ent)
                offset += cur_ent.byte_size
            elif ent_type == 128:
                cur_ent = Dummy_0.decode(data, offset, debug)
                cmap.entities.append(cur_ent)
                offset += cur_ent.byte_size
            else:
                raise ValueError(
                    f"Unknown entity type: {ent_type} at {offset - 1}")
            ent_done += 1
        if debug:
            print(offset, " / ", len(data), " consumed")
        if offset != len(data):
            raise ValueError("Not all bytes were consumed")

        ecmap = ECMap()
        ecmap.cmap = cmap
        return ecmap