def destruct(self, obj): log.debug("destructing %s", obj) obj.on_destruction() out = BitStream() out.write(c_ubyte(Message.ReplicaManagerDestruction)) out.write(c_ushort(self._network_ids[obj])) for participant in self._participants: self.send(out, participant) del self._network_ids[obj]
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)
def serialize(self, obj): out = BitStream() out.write(c_ubyte(Message.ReplicaManagerSerialize)) out.write(c_ushort(self._network_ids[obj])) out.write(obj.serialize()) for participant in self._participants: self.send(out, participant)
def construct(self, obj, recipients=None, new=True): # recipients is needed to send replicas to new participants if recipients is None: recipients = self._participants if new: self._network_ids[obj] = self._current_network_id self._current_network_id += 1 out = BitStream() out.write(c_ubyte(Message.ReplicaManagerConstruction)) out.write(c_bit(True)) out.write(c_ushort(self._network_ids[obj])) out.write(obj.send_construction()) for recipient in recipients: self.send(out, recipient)
def on_connection_request(self, data, address): packet_password = data if self.incoming_password == packet_password: response = BitStream() response.write(c_ubyte(Message.ConnectionRequestAccepted)) response.write(socket.inet_aton(address[0])) response.write(c_ushort(address[1])) response.write( bytes(2) ) # Connection index, seems like this was right out ignored in RakNet response.write(socket.inet_aton(self._address[0])) response.write(c_ushort(self._address[1])) self.send(response, address, reliability=PacketReliability.Reliable) else: raise NotImplementedError
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)