def from_binary(self, uuid, version=None): if len(uuid) != 16: raise Exception("Must have exactly 16 bytes") return UUID(Binary.read_int(Utils.substr(uuid, 0, 4)), Binary.read_int(Utils.substr(uuid, 4, 4)), Binary.read_int(Utils.substr(uuid, 8, 4)), Binary.read_int(Utils.substr(uuid, 12, 4)), version)
def from_binary(binary: bytes): packet = EncapsulatedPacket() flags = binary[0] reliability = (flags & 0b111 << 5) >> 5 has_split = (flags & 0b00010000) > 0 packet.reliability = reliability packet.has_split = has_split length = int(ceil(Binary.read_short(binary[1:2])) / 8) offset = 3 if PacketReliability.is_reliable(reliability): packet.message_index = Binary.read_l_triad(binary[offset:3]) offset += 3 if PacketReliability.is_sequenced(reliability): packet.sequence_index = Binary.read_l_triad(binary[offset:3]) offset += 3 if PacketReliability.is_sequenced_or_ordered(reliability): packet.order_index = Binary.read_l_triad(binary[offset:3]) offset += 3 packet.order_channel = binary[offset + 1] if has_split: packet.split_count = Binary.read_int(binary[offset:4]) offset += 4 packet.split_id = Binary.read_short(binary[offset:2]) offset += 2 packet.split_index = Binary.read_int(binary[offset:4]) offset += 4 packet.buffer = binary[offset:length] offset += length return packet
def from_internal_binary(binary_bytes: bytes): packet = EncapsulatedPacket() offset = 0 offset += 1 packet.reliability = binary_bytes[offset] length = Binary.read_int(binary_bytes[offset:4]) offset += 4 packet.identifier_ack = Binary.read_int( binary_bytes[offset:4] ) # TODO: don't read this for non-ack-receipt reliabilities offset += 4 if PacketReliability.is_sequenced_or_ordered(packet.reliability): offset += 1 packet.order_channel = binary_bytes[offset] packet.buffer = binary_bytes[offset:length] offset += length return packet
def handle_packet(self): packet = self.server.read_thread_to_main_packet() if packet is None: return packet_id = ord(packet[0]) offset = 1 if packet_id == PyRakLib.PACKET_ENCAPSULATED: offset += 1 length = ord(packet[offset]) identifier = packet[offset:length] offset += length flags = ord(packet[offset]) buffer = packet[offset] self.instance.handle_encapsulated( identifier, EncapsulatedPacket.from_internal_binary(buffer), flags) elif packet_id == PyRakLib.PACKET_RAW: length = ord(packet[offset + 1]) address = packet[offset:length] offset += length port = Binary.read_short(packet[offset:2]) offset += 2 payload = packet[offset:] self.instance.handle_raw(address, port, payload) elif packet_id == PyRakLib.PACKET_SET_OPTION: length = ord(packet[offset + 1]) name = packet[offset:length] offset += length value = packet[offset:] self.instance.handle_option(name, value) elif packet_id == PyRakLib.PACKET_OPEN_SESSION: length = ord(packet[offset + 1]) identifier = packet[offset:length] offset += length length = ord(packet[offset + 1]) address = packet[offset:length] offset += length port = Binary.read_short(packet[offset:2]) offset += 2 client_id = Binary.read_long(packet[offset:8]) self.instance.open_session(identifier, address, port, client_id) elif packet_id == PyRakLib.PACKET_CLOSE_SESSION: length = ord(packet[offset + 1]) identifier = packet[offset:length] offset += length length = ord(packet[offset + 1]) reason = packet[offset:length] self.instance.close_session(identifier, reason) elif packet_id == PyRakLib.PACKET_INVALID_SESSION: length = ord(packet[offset + 1]) identifier = packet[offset:length] self.instance.close_session(identifier, "Invalid session") elif packet_id == PyRakLib.PACKET_ACK_NOTIFICATION: length = ord(packet[offset + 1]) identifier = packet[offset:length] offset += length identifier_ack = Binary.read_int(packet[offset:4]) self.instance.notify_ack(identifier, identifier_ack) elif packet_id == PyRakLib.PACKET_REPORT_PING: length = ord(packet[offset + 1]) identifier = packet[offset:length] offset += length ping_ms = Binary.read_int(packet[offset:4]) self.instance.update_ping(identifier, ping_ms) return False
def receive_stream(self) -> bool: packet = self.server.read_main_to_thread_packet() if packet == b'': return False if len(packet) > 0: packet_id = ord(packet[0]) offset = 1 if packet_id == PyRakLib.PACKET_ENCAPSULATED: length = packet[offset] identifier = packet[offset:offset + length] offset += length session = self.sessions[identifier] or None if session is not None and session.is_connected(): offset += 1 flags = packet[offset] buffer = packet[offset:] session.add_encapsulated_to_queue(EncapsulatedPacket.from_internal_binary(buffer), flags) else: self.stream_invalid(packet) elif packet_id == PyRakLib.PACKET_RAW: length = packet[offset] address = packet[offset:length] offset += length port = Binary.read_short(packet[offset:2]) offset += 2 payload = packet[offset:] self.socket.write_packet(payload, address, port) elif packet_id == PyRakLib.PACKET_CLOSE_SESSION: offset += 1 length = packet[offset] packet_id = packet[offset:length] if packet_id in self.sessions: self.sessions[packet_id].flag_for_disconnection() else: self.stream_invalid(packet_id) elif packet_id == PyRakLib.PACKET_INVALID_SESSION: offset += 1 length = packet[offset] packet_id = packet[offset:length] if packet_id in self.sessions: self.remove_session(self.sessions[packet_id]) elif packet_id == PyRakLib.PACKET_SET_OPTION: length = ord(packet[offset]) offset += 1 name = packet[offset:offset + length] offset += length value = packet[offset:] if name == "servername": # print(name+b" "+value) self.name = value elif name == "portChecking": self.port_checking = bool(value) elif name == "packetLimit": self.packet_limit = int(value) else: pass # self.server.logger.error("Invalid option: "+name+" "+value) elif packet_id == PyRakLib.PACKET_BLOCK_ADDRESS: offset += 1 length = packet[offset] address = packet[offset:length] offset += length timeout = Binary.read_int(packet[offset:4]) self.block_address(address, timeout) elif packet_id == PyRakLib.PACKET_UNBLOCK_ADDRESS: offset += 1 length = packet[offset] address = packet[offset:length] self.unblock_address(address) elif packet_id == PyRakLib.PACKET_SHUTDOWN: for session in self.sessions: self.remove_session(session) self.socket.close() self.shutdown = True elif packet_id == PyRakLib.PACKET_EMERGENCY_SHUTDOWN: self.shutdown = True else: print("Unknown raklib internal packet " + str(packet_id)) return True return False
def get_int(self) -> int: return Binary.read_int(self.get(4))