def _send_packet(self, data, message_number, reliability, ordering_index, split_packet_id, split_packet_index, split_packet_count): out = BitStream() out.write(c_bit(len(self._acks) != 0)) if self._acks: out.write(c_uint(self._remote_system_time)) out.write(self._acks.serialize()) self._acks.clear() assert len(out) + ReliabilityLayer.packet_header_length(reliability, split_packet_id is not None) + len(data) < 1492 has_remote_system_time = False # time is only used for us to get back to calculate ping, and we don't do that out.write(c_bit(has_remote_system_time)) #out.write(c_uint(remote_system_time)) out.write(c_uint(message_number)) out.write_bits(reliability, 3) if reliability in (PacketReliability.UnreliableSequenced, PacketReliability.ReliableOrdered): out.write_bits(0, 5) # ordering_channel, no one ever uses anything else than 0 out.write(c_uint(ordering_index)) is_split_packet = split_packet_id is not None out.write(c_bit(is_split_packet)) if is_split_packet: out.write(c_ushort(split_packet_id)) out.write(c_uint(split_packet_index), compressed=True) out.write(c_uint(split_packet_count), compressed=True) out.write(c_ushort(len(data) * 8), compressed=True) out.align_write() out.write(data) assert len(out) < 1492 # maximum packet size handled by raknet self._transport.sendto(out, self._address)
def serialize(self, stream: bitstream.WriteStream) -> None: key_num = len(self._keys) stream.write(bitstream.c_uint(key_num)) for key in self._keys: name = key[0] value = key[1] value_type = key[2] stream.write(bitstream.c_uint8(len(name) * 2)) for char in name: stream.write(char.encode('latin1')) stream.write(b'\0') stream.write(bitstream.c_ubyte(value_type)) if value_type == 0: stream.write(value, length_type=bitstream.c_uint) elif value_type == 1: stream.write(bitstream.c_int(value)) elif value_type == 3: stream.write(bitstream.c_float(value)) elif value_type == 5: stream.write(bitstream.c_uint(value)) elif value_type == 7: stream.write(bitstream.c_bool(value)) elif value_type == 8 or value_type == 9: stream.write(bitstream.c_int64(value)) elif value_type == 13: xml_str = bytes(ElementTree.tostring(value)) xml_str = b'<?xml version="1.0">' + xml_str stream.write(bitstream.c_ulong(xml_str.__len__())) stream.write(xml_str)
def serialize(self): """ Serialize the RangeList. This is meant to be compatible with RakNet's serialization. (This currently serializes items as uints, since currently the only occurence where I need to serialize a rangelist is with an uint) """ out = BitStream() out.write(c_ushort(len(self)), compressed=True) for range in self: out.write(c_bit(range[0] == range[1])) out.write(c_uint(range[0])) if range[0] != range[1]: out.write(c_uint(range[1])) return out
def _send_loop(self): for packet in self._sends: data, reliability, ordering_index, split_packet_id, split_packet_index, split_packet_count = packet message_number = self._send_message_number_index self._send_message_number_index += 1 self._send_packet(data, message_number, reliability, ordering_index, split_packet_id, split_packet_index, split_packet_count) if reliability == PacketReliability.Reliable or reliability == PacketReliability.ReliableOrdered: self._resends[message_number] = time.time()+1, packet self._sends.clear() for message_number, resend_data in self._resends.items(): resend_time, packet = resend_data if resend_time > time.time(): continue log.info("actually resending %i", message_number) data, reliability, ordering_index, split_packet_id, split_packet_index, split_packet_count = packet self._send_packet(data, message_number, reliability, ordering_index, split_packet_id, split_packet_index, split_packet_count) if reliability == PacketReliability.Reliable or reliability == PacketReliability.ReliableOrdered: self._resends[message_number] = time.time()+1, packet if self._acks: out = BitStream() out.write(c_bit(True)) out.write(c_uint(self._remote_system_time)) out.write(self._acks.serialize()) self._acks.clear() self._transport.sendto(out, self._address) if not self.stop: asyncio.get_event_loop().call_later(0.03, self._send_loop)
def on_internal_ping(self, data, address): ping_send_time = data[:4] pong = BitStream() pong.write(c_ubyte(Message.ConnectedPong)) pong.write(ping_send_time) pong.write(c_uint(int(time.perf_counter() * 1000))) self.send(pong, address, PacketReliability.Unreliable)