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 _encode(self): super().clean() payload = bytearray() self.seqNums = sorted(self.seqNums) count = len(self.seqNums) records = 0 if count > 0: pointer = 1 start = self.seqNums[0] last = self.seqNums[0] while pointer < count: pointer += 1 if pointer == count: break current = self.seqNums[pointer] diff = current - last if diff == 1: last = current elif diff > 1: if start == last: payload += bytes("\x01", "UTF-8") payload += (Binary.writeLTriad(start)) start = last = current else: payload += bytes("\x01", "UTF-8") payload += (Binary.writeLTriad(start)) payload += (Binary.writeLTriad(last)) start = last = current records = +1 if start == last: payload += bytes("\x01", "UTF-8") payload += (Binary.writeLTriad(start)) start = last = current else: payload += bytes("\x01", "UTF-8") payload += (Binary.writeLTriad(start)) payload += (Binary.writeLTriad(last)) start = last = current self.putByte(self.getPID(), False) self.putShort(records) self.put(payload)
def streamACK(self, identifier, identifierACK): buffer = chr(NetLib.PACKET_ACK_NOTIFICATION) + chr(len(identifier)) + identifier + str(Binary.writeInt(identifierACK)) self.server.pushThreadToMainPacket(buffer)
def streamRaw(self, address, port, payload): buffer = chr(NetLib.PACKET_RAW) + chr(len(address)) + address + Binary.writeShort(port) + payload self.server.pushThreadToMainPacket(buffer)
def putString(self, string: str): self.buffer += Binary.writeShort(len(string)) self.buffer += bytes(string, "UTF-8")
def putLTriad(self, t: int): self.buffer += Binary.writeLTriad(t)
def toBinary(self, internal=False): payload = bytearray() if self.hasSplit: payload += (Binary.writeByte((self.reliability << 5) | 0b00010000)) else: payload += (Binary.writeByte(self.reliability << 5)) if internal: payload += (Binary.writeInt(len(self.buffer))) payload += (Binary.writeInt(self.identifierACK)) else: payload += (Binary.writeShort(len(self.buffer) << 3)) if self.reliability > 0: if (self.reliability > 2 or self.reliability == 2) and self.reliability is not 5: payload += (Binary.writeLTriad(self.messageIndex)) if (self.reliability < 4 or self.reliability == 4) and self.reliability is not 2: payload += (Binary.writeLTriad(self.orderIndex)) payload += (Binary.writeByte(self.orderChannel)) if self.hasSplit: payload += (Binary.writeInt(self.splitCount)) payload += (Binary.writeShort(self.splitID)) payload += (Binary.writeInt(self.splitIndex)) payload += (self.buffer) return payload
def blockAddress(self, address: str, timeout: int): buffer = chr(NetLib.PACKET_BLOCK_ADDRESS) + chr(len(address)) + address + str(Binary.writeInt(timeout)) self.server.pushMainToThreadPacket(buffer)
def putLong(self, l: int): self.buffer += Binary.writeLong(l)
def putByte(self, b: int, signed: bool = True): self.buffer += Binary.writeByte(b, signed)
def getLTriad(self) -> int: return Binary.readLTriad(self.get(3))
def getShort(self) -> int: return Binary.readShort(self.get(2))
def getInt(self) -> int: return Binary.readInt(self.get(4))
def getLong(self) -> int: return Binary.readLong(self.get(8))
def receiveStream(self): packet = self.server.readMainToThreadPacket() if packet == None: return False if len(packet) > 0: id = ord(packet[0]) offset = 1 if id == NetLib.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 == NetLib.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 == NetLib.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 == NetLib.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 == NetLib.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 == NetLib.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 == NetLib.PACKET_SHUTDOWN: for session in self.sessions: del session self.socket.close() self.shutdown = True elif id == NetLib.PACKET_EMERGENCY_SHUTDOWN: self.shutdown = True else: return False return True
def sendRaw(self, address: str, port: int, payload: bytearray): buffer = chr(NetLib.PACKET_RAW) + chr(len(address)) + address + str(Binary.writeShort(port)) + payload self.server.pushMainToThreadPacket(buffer)
def putInt(self, i: int): self.buffer += Binary.writeInt(i)
def handlePacket(self): packet = self.server.readThreadToMainPacket() if packet == None: return if len(packet) > 0: id = ord(packet[0]) offset = 1 if id == NetLib.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 == NetLib.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 == NetLib.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 == NetLib.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 == NetLib.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 == NetLib.PACKET_INVALID_SESSION: offset += 1 length = ord(packet[offset]) identifier = packet[offset:offset+length] self.instance.closeSession(identifier, "Invalid session") elif id == NetLib.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 putShort(self, s: int): self.buffer += Binary.writeShort(s)