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: WriteStream): stream.write(c_bit(True)) stream.write(c_bit(False)) stream.write(c_bit(False)) for c in self.components: c.serialize(stream)
def write_construction(self, stream: WriteStream): stream.write(c_int64(self.object_id)) stream.write(c_int32(self.lot)) stream.write(self.name, length_type=c_uint8) stream.write(c_uint32(self.time_since_created)) stream.write(c_bit(False)) stream.write(c_bit(self.trigger)) stream.write(c_bit(self.spawner_id is not None)) if self.spawner_id is not None: stream.write(c_int64(self.spawner_id)) stream.write(c_bit(self.spawner_node_id is not None)) if self.spawner_node_id is not None: stream.write(c_uint32(self.spawner_node_id)) stream.write(c_bit(self.scale is not None)) if self.scale is not None: stream.write(c_float(self.scale)) stream.write(c_bit(False)) stream.write(c_bit(False)) stream.write(c_bit(True)) stream.write(c_bit(False)) stream.write(c_bit(False)) for c in self.components: c.construct(stream)
def serialize(self, stream: WriteStream): stream.write(c_bit(True)) stream.write(c_uint32(len(self.items))) for item in self.items: stream.write(item) stream.write(c_bit(True)) stream.write(c_uint32(0))
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 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 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 _write_part2(self, stream: WriteStream): stream.write(c_bit(True)) stream.write(c_bit(self.pvp)) stream.write(c_bit(self.gm)) stream.write(c_uint8(self.gm_level)) stream.write(c_bit(False)) stream.write(c_uint8(0)) stream.write(c_bit(True)) stream.write(c_uint32(1 if self.glowing_head else 0)) stream.write(c_bit(self.guild)) if self.guild: stream.write(c_int64(self.guild_id)) stream.write(self.guild_name, allocated_length=33) stream.write(c_bit(True)) stream.write(c_int32(-1))
def _write_part1(self, stream: WriteStream): stream.write(c_bit(True)) stream.write(c_bit(self.vehicle_id is not None)) if self.vehicle_id is not None: stream.write(c_int64(self.vehicle_id)) stream.write(c_uint8(0)) stream.write(c_bit(self.level is not None)) if self.level is not None: stream.write(c_uint32(self.level)) stream.write(c_bit(True)) stream.write(c_bit(False)) stream.write(c_bit(True))
def serialize(self, stream: WriteStream): stream.write(c_int64(self.object_id)) stream.write(c_int32(self.lot)) stream.write(c_bit(False)) stream.write(c_bit(self.amount is not None)) if self.amount is not None: stream.write(c_uint32(self.amount)) stream.write(c_bit(self.slot is not None)) if self.slot is not None: stream.write(c_uint16(self.slot)) stream.write(c_bit(True)) stream.write(c_uint32(4)) stream.write(c_bit(False)) # TODO: implement metadata stream.write(c_bit(False))
def serialize(self, stream: WriteStream): stream.write(c_bit(True)) stream.write(c_int64(0))
def construct(self, stream: WriteStream): self._write_part1(stream) stream.write(c_bit(False)) stream.write(c_bit(False)) stream.write(c_bit(False)) stream.write(c_bit(False)) stream.write(c_uint32(self.hair_color)) stream.write(c_uint32(self.hair_style)) stream.write(c_uint32(0)) stream.write(c_uint32(self.shirt_color)) stream.write(c_uint32(self.pants_color)) stream.write(c_uint32(self.shirt_style)) stream.write(c_uint32(0)) stream.write(c_uint32(self.eyebrow_style)) stream.write(c_uint32(self.eye_style)) stream.write(c_uint32(self.mouth_style)) stream.write(c_uint64(self.account_id)) stream.write(c_uint64(self.llog)) stream.write(c_uint64(0)) stream.write(c_uint64(self.lego_score)) stream.write(c_bit(self.free_to_play)) stream.write(c_uint64(self.currency_collected)) stream.write(c_uint64(self.bricks_collected)) stream.write(c_uint64(self.smashables_smashed)) stream.write(c_uint64(self.quickbuilds_completed)) stream.write(c_uint64(self.enemies_smashed)) stream.write(c_uint64(self.rockets_used)) stream.write(c_uint64(self.missions_completed)) stream.write(c_uint64(self.pets_tamed)) stream.write(c_uint64(self.imagination_powerups_collected)) stream.write(c_uint64(self.life_powerups_collected)) stream.write(c_uint64(self.armor_powerups_collected)) stream.write(c_uint64(self.distance_traveled)) stream.write(c_uint64(self.times_smashed)) stream.write(c_uint64(self.damage_taken)) stream.write(c_uint64(self.damage_healed)) stream.write(c_uint64(self.armor_repaired)) stream.write(c_uint64(self.imagination_restored)) stream.write(c_uint64(self.imagination_used)) stream.write(c_uint64(self.distance_driven)) stream.write(c_uint64(self.time_airborne_racecar)) stream.write(c_uint64(self.racing_imagination_powerups_collected)) stream.write(c_uint64(self.racing_imagination_crates_smashed)) stream.write(c_uint64(self.racecar_boosts_activated)) stream.write(c_uint64(self.racecar_wrecks)) stream.write(c_uint64(self.racing_smashables_smashed)) stream.write(c_uint64(self.races_finished)) stream.write(c_uint64(self.first_place_finishes)) stream.write(c_bit(False)) stream.write(c_bit(self.landing_rocket)) if self.landing_rocket: stream.write(self.rocket_modules, length_type=c_uint16) self._write_part2(stream)
def construct(self, stream: WriteStream): stream.write(c_bit(False))