def fromBinary(binary, internal=False, offset=None): if isinstance(binary, str): binary = bytes(binary, "UTF-8") packet = EncapsulatedPacket() flags = binary[0] packet.reliability = (flags & 0b11100000) >> 5 packet.hasSplit = (flags & 0b00010000) > 0 if internal: length = Binary.readInt(binary[1:5]) packet.identifierACK = Binary.readInt(binary[5:9]) offset = 9 else: length = int(Binary.readShort(binary[1:3]) / 8) offset = 3 packet.identifierACK = None if packet.reliability > 0: if (packet.reliability > 2 or packet.reliability == 2) and packet.reliability is not 5: packet.messageIndex = Binary.readLTriad(binary[offset:offset + 3]) offset += 3 if (packet.reliability < 4 or packet.reliability == 4) and packet.reliability is not 2: packet.orderIndex = Binary.readLTriad(binary[offset:offset + 3]) offset += 3 packet.orderChannel = Binary.readByte(binary[offset:offset + 1]) offset += 1 if packet.hasSplit: packet.splitCount = Binary.readInt(binary[offset:offset + 4]) offset += 4 packet.splitID = Binary.readShort(binary[offset:offset + 2]) offset += 2 packet.splitIndex = binary.readInt(binary[offset:offset + 4]) offset += 4 packet.buffer = binary[offset:offset + length] offset += length return packet, offset
def handlePacket(self): packet = self.server.readThreadToMainPacket() if packet is None: return if len(packet) > 0: id = ord(packet[0]) offset = 1 if id == PyRakLib.PACKET_ENCAPSULATED: offset += 1 length = ord(packet[offset]) identifier = packet[offset:offset + length] offset += length + 1 flags = ord(packet[offset]) buffer = packet[offset:] self.instance.handleEncapsulated( identifier, EncapsulatedPacket.fromBinary(buffer, True), flags) elif id == PyRakLib.PACKET_RAW: length = ord(packet[offset]) offset += 1 address = packet[offset:offset + length] offset += length port = Binary.readShort(packet[offset:offset + 2]) offset += 2 payload = packet[offset:] self.instance.handleRaw(address, port, payload) elif id == PyRakLib.PACKET_SET_OPTION: length = ord(packet[offset]) offset += 1 name = packet[offset:offset + length] offset += length value = packet[offset:] self.instance.handleOption(name, value) elif id == PyRakLib.PACKET_OPEN_SESSION: offset += 1 length = ord(packet[offset]) identifier = packet[offset:offset + length] offset += length + 1 length = ord(packet[offset]) address = packet[offset:offset + length] offset += len port = Binary.readShort(packet[offset:offset + 2]) offset += 2 clientID = Binary.readLong(packet[offset:offset + 8]) self.instance.openSession(identifier, address, port, clientID) elif id == PyRakLib.PACKET_CLOSE_SESSION: length = ord(packet[offset]) offset += 1 identifier = packet[offset:offset + length] offset += length length = ord(packet[offset]) offset += 1 reason = packet[offset:offset + length] self.instance.closeSession(identifier, reason) elif id == PyRakLib.PACKET_INVALID_SESSION: offset += 1 length = ord(packet[offset]) identifier = packet[offset:offset + length] self.instance.closeSession(identifier, "Invalid session") elif id == PyRakLib.PACKET_ACK_NOTIFICATION: offset += 1 length = ord(packet[offset]) identifier = packet[offset:offset + length] offset += length identifierACK = Binary.readInt(packet[offset:offset + 4]) self.instance.notifyACK(identifier, identifierACK) return True return False
def getShort(self) -> int: return Binary.readShort(self.get(2))
def receiveStream(self): packet = self.server.readMainToThreadPacket() if packet == None: return False if len(packet) > 0: id = ord(packet[0]) offset = 1 if id == PyRakLib.PACKET_ENCAPSULATED: length = ord(packet[offset]) identifier = packet[offset:offset + length] offset += length + 1 try: self.sessions[identifier] flags = ord(packet[offset]) buffer = packet[offset:] self.sessions[identifier].addEncapsulatedToQueue(EncapsulatedPacket.fromBinary(buffer, True), flags) except NameError: self.streamInvalid(identifier) elif id == PyRakLib.PACKET_RAW: length = ord(packet[offset]) address = packet[offset:offset + length] offset += length port = Binary.readShort(packet[offset:offset + 2]) offset += 2 payload = packet[offset:] self.socket.writePacket(payload, address, port) elif id == PyRakLib.PACKET_SET_OPTION: length = ord(packet[offset]) offset += 1 name = packet[offset:offset + length] offset += length value = packet[offset:] if name == "name": print(name + " " + value) self.name = value elif name == "portChecking": self.portChecking = bool(value) elif name == "packetLimit": self.packetLimit = int(value) else: pass # self.server.logger.error("Invalid option: "+name+" "+value) elif id == PyRakLib.PACKET_CLOSE_SESSION: length = ord(packet[offset]) offset += 1 identifier = packet[offset:offset + length] offset += length + 1 length = ord(packet[offset]) reason = packet[offset:offset + length] try: s = self.sessions[identifier] self.removeSession(s) except KeyError: self.streamInvalid(identifier) elif id == PyRakLib.PACKET_INVALID_SESSION: length = ord(packet[offset]) offset += 1 identifier = packet[offset:offset + length] try: self.removeSession(self.sessions[identifier]) except KeyError: pass elif id == PyRakLib.PACKET_BLOCK_ADDRESS: length = ord(packet[offset]) address = packet[offset:offset + length] offset += length timeout = Binary.readInt(packet[offset:offset + 4]) self.blockAddress(address, timeout) elif id == PyRakLib.PACKET_SHUTDOWN: for session in self.sessions: del session self.socket.close() self.shutdown = True elif id == PyRakLib.PACKET_EMERGENCY_SHUTDOWN: self.shutdown = True else: return False return True