예제 #1
0
 def deserialize(cls, stream: bitstream.ReadStream) -> bitstream.Serializable:
     result = Vector3()
     result.x = stream.read(bitstream.c_float)
     result.y = stream.read(bitstream.c_float)
     result.z = stream.read(bitstream.c_float)
     result.w = stream.read(bitstream.c_float)
     return result
예제 #2
0
    def deserialize(cls, stream: ReadStream) -> "PacketHeader":
        assert stream.read(c_uint8) == 0x53
        connection_type = stream.read(c_uint16)
        packet_id = stream.read(c_uint32)
        assert stream.read(c_uint8) == 0

        return cls(connection_type=connection_type, packet_id=packet_id)
예제 #3
0
 def deserialize(cls,
                 stream: bitstream.ReadStream) -> bitstream.Serializable:
     packet = ClientLoadCompletePacket()
     packet.zone_id = stream.read(bitstream.c_uint16)
     packet.map_instance = stream.read(bitstream.c_uint16)
     packet.map_clone = stream.read(bitstream.c_uint32)
     return packet
예제 #4
0
 def deserialize(cls,
                 stream: bitstream.ReadStream) -> bitstream.Serializable:
     packet = HandshakePacket()
     packet.game_version = stream.read(bitstream.c_uint32)
     packet.unknown_0 = stream.read(bitstream.c_uint32)
     packet.remote_connection_type = stream.read(bitstream.c_uint32)
     packet.process_id = stream.read(bitstream.c_uint32)
     packet.local_port = stream.read(bitstream.c_uint16)
     return packet
예제 #5
0
 def deserialize(cls, stream: bitstream.ReadStream) -> bitstream.Serializable:
     luz_scene = LUZScene()
     luz_scene.filename = CString(length_type=bitstream.c_uint8).deserialize(stream)
     luz_scene.id = stream.read(bitstream.c_uint8)
     stream.read(bytes, length=3)
     stream.read(bitstream.c_uint8)
     stream.read(bytes, length=3)
     luz_scene.name = CString(length_type=bitstream.c_uint8).deserialize(stream)
     stream.read(bytes, length=3)
     return luz_scene
예제 #6
0
    def construct_packet(self, packet):
        stream = ReadStream(packet)
        client_ver = stream.read(c_ulong)  # TODO - check client ver against server

        res = WriteStream()
        res.write(PacketHeaders.HANDSHAKE.value)
        res.write(c_ulong(171022))  # TODO - fix checking client ver
        res.write(c_ulong(0x93))
        res.write(c_ulong(4))
        res.write(c_ulong(os.getpid()))
        res.write(c_short(0xff))
        res.write(str(socket.gethostbyname(socket.gethostname())), allocated_length=33)

        return res
예제 #7
0
    def _on_packet(self, data: bytes, address: Address):
        stream = ReadStream(data)
        header = stream.read(PacketHeader)

        if header.connection_type in self._handlers and header.packet_id in self._handlers[
                header.connection_type]:
            tup = self._handlers[header.connection_type][header.packet_id]
            pkt = tup[0]

            self.log.info(f'Received packet {pkt.__name__}')

            tup[1](stream.read(pkt), address)
        else:
            self.log.warning(
                f'Unhandled packet ({header.connection_type}, {header.packet_id})'
            )
예제 #8
0
 def on_packet(self, data, address):
     packet = Packet.deserialize(ReadStream(data), self.server.packets)
     
     if getattr(packet.header,'packet_name', None) is None:
         self.server.handle('pkt:unknown_packet', packet)
     else:
         log.debug(f'[{self.server.type}] Recieved LU Packet {packet.header.packet_name}'
         self.server.handle(f'pkt:{packet.header.packet_name}', packet, address)
         
예제 #9
0
    def construct_packet(self, packet):
        stream = ReadStream(packet)

        # TODO - figure out why we aren't receiving user credentials correctly?
        """
        uname = stream.read(str, allocated_length=33)
        pword = stream.read(str, allocated_length=41)

        self.logger.debug('user with credentials {0}:{1} attempting to login'.format(uname, pword))
        """
        uname = 'dev'
        pword = 'dev'

        res = WriteStream()
        res.write(PacketHeaders.CLIENT_LOGIN_RES.value)

        for account in self.database.accounts:
            if account.username == uname and account.password == pword:
                self.logger.debug('found user {} in database'.format(uname))
                res.write(c_uint8(0x01))
                break
            elif account.banned:
                res.write(c_uint8(0x02))
                break

        res.write(CString('Talk_Like_A_Pirate',
                          allocated_length=33))  # unknown
        res.write(CString(allocated_length=33 * 7))  # unknown

        res.write(c_uint16(1))  # v. major
        res.write(c_uint16(10))  # v. current
        res.write(c_uint16(64))  # v. minor

        user_token = str(uuid.uuid4())
        res.write(user_token[0:18], allocated_length=33)

        res.write(CString('127.0.0.1', allocated_length=33))  # world IP
        res.write(CString('127.0.0.1', allocated_length=33))  # chat IP
        res.write(c_uint16(2002))  # world port
        res.write(c_ushort(3003))  # chat port
        res.write(CString('0', allocated_length=33))  # unknown IP

        res.write(
            CString('00000000-0000-0000-0000-000000000000',
                    allocated_length=37))
        res.write(c_ulong(0))
        res.write(CString('US', allocated_length=3))  # localization
        res.write(c_bool(False))
        res.write(c_bool(False))
        res.write(c_ulonglong(0))
        res.write('error', length_type=c_uint16)  # custom err msg
        res.write(c_uint16(0))
        res.write(c_ulong(4))

        return res
예제 #10
0
 def deserialize(cls, stream: bitstream.ReadStream) -> bitstream.Serializable:
     luz = LUZ()
     luz.version = stream.read(bitstream.c_ulong)
     if luz.version >= 0x24:
         stream.read(bitstream.c_ulong)
     luz.world_id = stream.read(bitstream.c_ulong)
     if luz.version >= 0x26:
         luz.spawnpoint_position = stream.read(Vector3)
         luz.spawnpoint_rotation = stream.read(Vector4)
     if luz.version < 0x25:
         scene_count = stream.read(bitstream.c_uint8)
     else:
         scene_count = stream.read(bitstream.c_ulong)
     for _ in range(scene_count):
         luz.scenes.append(stream.read(LUZScene))
     return luz
예제 #11
0
    def deserialize(cls, stream: ReadStream) -> "HandshakePacket":
        game_version = stream.read(c_uint32)
        assert stream.read(c_uint32) == 0
        remote_connection_type = stream.read(c_uint32)
        pid = stream.read(c_uint32)
        port = stream.read(c_uint16)
        ip = stream.read(bytes, allocated_length=33).decode('latin1')

        return cls(game_version=game_version,
                   remote_connection_type=remote_connection_type,
                   pid=pid,
                   port=port,
                   ip=ip)
예제 #12
0
 def deserialize(cls, stream: ReadStream):
     return cls(stream.read(c_uint16), stream.read(c_uint16),
                stream.read(c_uint32))
예제 #13
0
 def deserialize(cls,
                 stream: bitstream.ReadStream) -> bitstream.Serializable:
     packet = UserSessionInfoPacket()
     packet.username = stream.read(str, allocated_length=33)
     packet.user_key = stream.read(str, allocated_length=33)
     return packet
예제 #14
0
 def deserialize(cls,
                 stream: bitstream.ReadStream) -> bitstream.Serializable:
     packet = CharacterRenameRequestPacket()
     packet.object_id = stream.read(bitstream.c_int64)
     packet.new_name = stream.read(str, allocated_length=33)
     return packet
예제 #15
0
 def deserialize(cls, stream: ReadStream):
     return cls(stream.read(c_int64), stream.read(c_uint16),
                stream.read_remaining())
예제 #16
0
 def deserialize(cls, stream: ReadStream) -> "CharacterCreateRequest":
     return cls(name=stream.read(str, allocated_length=33),
                predef1=stream.read(c_uint32),
                predef2=stream.read(c_uint32),
                predef3=stream.read(c_uint32),
                unknown1=stream.read(bytes, allocated_length=9),
                shirt_color=stream.read(c_uint32),
                shirt_style=stream.read(c_uint32),
                pants_color=stream.read(c_uint32),
                hair_style=stream.read(c_uint32),
                hair_color=stream.read(c_uint32),
                lh=stream.read(c_uint32),
                rh=stream.read(c_uint32),
                eyebrow_style=stream.read(c_uint32),
                eye_style=stream.read(c_uint32),
                mouth_style=stream.read(c_uint32),
                unknown2=stream.read(c_uint8))
예제 #17
0
 def deserialize(cls, stream: ReadStream) -> "WorldJoinRequestPacket":
     return cls(stream.read(c_int64))
예제 #18
0
 def deserialize(cls,
                 stream: bitstream.ReadStream) -> bitstream.Serializable:
     packet = DisconnectNotifyPacket()
     packet.disconnect_id = stream.read(bitstream.c_uint32)
     return packet
예제 #19
0
 def deserialize(cls, stream: ReadStream) -> "SessionInfoPacket":
     return cls(stream.read(str, allocated_length=33),
                stream.read(str, allocated_length=33),
                stream.read(bytes, allocated_length=33).decode('latin1'))
예제 #20
0
 def deserialize(cls,
                 stream: bitstream.ReadStream) -> bitstream.Serializable:
     packet = LoginInfoPacket()
     packet.username = stream.read(str, allocated_length=33)
     packet.password = stream.read(str, allocated_length=41)
     return packet
예제 #21
0
 def deserialize(cls,
                 stream: bitstream.ReadStream) -> bitstream.Serializable:
     packet = MinifigureCreateRequestPacket()
     packet.name = stream.read(str, allocated_length=33)
     packet.predef_name_1 = stream.read(bitstream.c_uint32)
     packet.predef_name_2 = stream.read(bitstream.c_uint32)
     packet.predef_name_3 = stream.read(bitstream.c_uint32)
     packet.unknown_0 = stream.read(bitstream.c_uint8)
     packet.head_color = stream.read(bitstream.c_uint32)
     packet.head = stream.read(bitstream.c_uint32)
     packet.chest_color = stream.read(bitstream.c_uint32)
     packet.chest = stream.read(bitstream.c_uint32)
     packet.legs = stream.read(bitstream.c_uint32)
     packet.hair_style = stream.read(bitstream.c_uint32)
     packet.hair_color = stream.read(bitstream.c_uint32)
     packet.left_hand = stream.read(bitstream.c_uint32)
     packet.right_hand = stream.read(bitstream.c_uint32)
     packet.eyebrow_style = stream.read(bitstream.c_uint32)
     packet.eyes_style = stream.read(bitstream.c_uint32)
     packet.mouth_style = stream.read(bitstream.c_uint32)
     return packet
예제 #22
0
 def deserialize(cls,
                 stream: bitstream.ReadStream) -> bitstream.Serializable:
     packet = JoinWorldPacket()
     packet.object_id = stream.read(bitstream.c_int64)
     return packet
예제 #23
0
    def _parse_chunk_2001(stream: ReadStream) -> List[LegoObject]:
        objects = []

        object_count = stream.read(c_uint32)

        for _ in range(object_count):
            object_id = stream.read(c_uint64)
            lot = stream.read(c_int32)

            stream.read(c_uint32)
            stream.read(c_uint32)

            position = Vector3(stream.read(c_float), stream.read(c_float),
                               stream.read(c_float))
            rotation = Quaternion(w=stream.read(c_float), x=stream.read(c_float), y=stream.read(c_float),\
                                  z=stream.read(c_float))
            scale = stream.read(c_float)

            ldf_config = stream.read(str, length_type=c_uint32)
            config = parse_ldf(ldf_config)

            assert stream.read(c_uint32) == 0

            if lot != 176:
                continue

            spawntemplate = config['spawntemplate']

            objects.append(
                LegoObject(object_id, spawntemplate, position, rotation, scale,
                           config))

        return objects
예제 #24
0
 def deserialize(self, stream: bitstream.ReadStream):
     return stream.read(bytes, allocated_length=self.allocated_length, length_type=self.length_type).decode('latin1')
예제 #25
0
    def _parse_level(stream: ReadStream) -> List[LegoObject]:
        header = stream.read(bytes, length=4)

        stream.read_offset = 0

        objects = []

        if header == b'CHNK':
            while not stream.all_read():
                assert stream.read_offset // 8 % 16 == 0

                start_pos = stream.read_offset // 8

                assert stream.read(bytes, length=4) == b'CHNK'

                chunk_type = stream.read(c_uint32)

                stream.read(c_uint16)
                stream.read(c_uint16)

                chunk_length = stream.read(c_uint32)
                data_pos = stream.read(c_uint32)

                stream.read_offset = data_pos * 8

                assert stream.read_offset // 8 % 16 == 0

                if chunk_type == 2001:
                    objects.extend(ZoneReader._parse_chunk_2001(stream))

                stream.read_offset = (start_pos + chunk_length) * 8

        return objects
예제 #26
0
 def deserialize(cls,
                 stream: bitstream.ReadStream) -> bitstream.Serializable:
     packet = GeneralNotifyPacket()
     packet.notify_id = stream.read(bitstream.c_uint32)
     return packet
예제 #27
0
    def parse_zone(zone: int) -> LegoZone:
        if zone in ZoneReader._cache:
            return ZoneReader._cache[zone]

        with open(ZONE_FILES[zone], 'rb') as f:
            stream = ReadStream(f.read(), unlocked=True)

        version = stream.read(c_uint32)

        assert 0x30 > version > 0x24

        stream.read(c_uint32)

        world_id = stream.read(c_uint32)

        spawnpoint_pos = Vector3(stream.read(c_float), stream.read(c_float),
                                 stream.read(c_float))
        spawnpoint_rot = Quaternion(stream.read(c_float), stream.read(c_float),
                                    stream.read(c_float), stream.read(c_float))

        scene_count = stream.read(c_uint32)
        scenes = []

        for _ in range(scene_count):
            filename = stream.read(bytes, length_type=c_uint8).decode('latin1')

            scene_id = stream.read(c_uint64)

            scene_name = stream.read(bytes,
                                     length_type=c_uint8).decode('latin1')

            stream.read(bytes, length=3)

            pth = os.path.join(os.path.realpath(''), 'assets', 'levels',
                               filename)

            objects = []

            if os.path.exists(pth):
                with open(pth, 'rb') as f:
                    objects = ZoneReader._parse_level(
                        ReadStream(f.read(), unlocked=True))

            scenes.append(LegoScene(scene_id, scene_name, objects))

        return LegoZone(world_id, spawnpoint_pos, spawnpoint_rot, scenes)
예제 #28
0
 def deserialize(cls, stream: ReadStream) -> "LoginInfoPacket":
     return cls(username=stream.read(str, allocated_length=33),
                password=stream.read(str, allocated_length=41),
                lang_id=stream.read(c_uint16),
                platform_type=stream.read(c_uint8),
                memory_info=stream.read(str, allocated_length=256),
                gpu_info=stream.read(str, allocated_length=128),
                cpu_cores=stream.read(c_uint32),
                cpu_type=stream.read(c_uint32),
                cpu_lvl=stream.read(c_uint16),
                cpu_rev=stream.read(c_uint16),
                unknown1=stream.read(c_uint32),
                os_major_ver=stream.read(c_uint32),
                os_minor_ver=stream.read(c_uint32),
                os_build_num=stream.read(c_uint32),
                os_platform_id=stream.read(c_uint32))
예제 #29
0
 def deserialize(cls,
                 stream: bitstream.ReadStream) -> bitstream.Serializable:
     packet = CharacterDeleteRequestPacket()
     packet.object_id = stream.read(bitstream.c_int64)
     return packet