Esempio n. 1
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")
Esempio n. 2
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)
Esempio n. 3
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
Esempio n. 4
0
    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
Esempio n. 5
0
    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