def _handle_a2s_multi_packet_response(sock, packet):
    packets, payload_offset = [packet], -1

    # locate first packet and handle out of order packets
    while payload_offset == -1:
        # locate payload offset in uncompressed packet
        payload_offset = packet.find(b'\xff\xff\xff\xff', 0, 18)

        # locate payload offset in compressed packet
        if payload_offset == -1:
            payload_offset = packet.find(b'BZh', 0, 21)

        # if we still haven't found the offset receive the next packet
        if payload_offset == -1:
            packet = sock.recv(2048)
            packets.append(packet)

    # read header
    pkt_idx, num_pkts, compressed = _unpack_multipacket_header(
        payload_offset, packet)

    if pkt_idx != 0:
        raise RuntimeError("Unexpected first packet index")

    # recv any remaining packets
    while len(packets) < num_pkts:
        packets.append(sock.recv(2048))

    # ensure packets are in correct order
    packets = sorted(map(
        lambda pkt: (_unpack_multipacket_header(payload_offset, pkt)[0], pkt),
        packets,
    ),
                     key=lambda x: x[0])

    # reconstruct full response
    data = b''.join(map(lambda x: x[1][payload_offset:], packets))

    # decompress response if needed
    if compressed:
        size, checksum = _unpack_from('<ll', packet, 10)
        data = _bz2_decompress(data)

        if len(data) != size:
            raise RuntimeError("Response size mismatch - %d %d" %
                               (len(data), size))
        if checksum != crc32(data):
            raise RuntimeError("Response checksum mismatch - %d %d" %
                               (checksum, crc32(data)))

    return data
Ejemplo n.º 2
0
def _handle_a2s_multi_packet_response(sock, packet):
    packets, payload_offset = [packet], -1

    # locate first packet and handle out of order packets
    while payload_offset == -1:
        # locate payload offset in uncompressed packet
        payload_offset = packet.find(b'\xff\xff\xff\xff', 0, 18)

        # locate payload offset in compressed packet
        if payload_offset == -1:
            payload_offset = packet.find(b'BZh', 0, 21)

        # if we still haven't found the offset receive the next packet
        if payload_offset == -1:
            packet = sock.recv(2048)
            packets.append(packet)

    # read header
    pkt_idx, num_pkts, compressed = _unpack_multipacket_header(payload_offset, packet)

    if pkt_idx != 0:
        raise RuntimeError("Unexpected first packet index")

    # recv any remaining packets
    while len(packets) < num_pkts:
        packets.append(sock.recv(2048))

    # ensure packets are in correct order
    packets = sorted(map(lambda pkt: (_unpack_multipacket_header(payload_offset, pkt)[0], pkt),
                         packets,
                         ),
                     key=lambda x: x[0])

    # reconstruct full response
    data = b''.join(map(lambda x: x[1][payload_offset:], packets))

    # decompress response if needed
    if compressed:
        size, checksum = _unpack_from('<ll', packet, 10)
        data = _bz2_decompress(data)

        if len(data) != size:
            raise RuntimeError("Response size mismatch - %d %d" % (len(data), size))
        if checksum != crc32(data):
            raise RuntimeError("Response checksum mismatch - %d %d" % (checksum, crc32(data)))

    return data