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 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 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_packet(self, packet): stream = ReadStream(packet) # TODO - figure out why we aren't receiving user credentials correctly? """ uname = stream.read(str, allocated_length=33) pword = stream.read(str, allocated_length=41) self.logger.debug('user with credentials {0}:{1} attempting to login'.format(uname, pword)) """ uname = 'dev' pword = 'dev' res = WriteStream() res.write(PacketHeaders.CLIENT_LOGIN_RES.value) for account in self.database.accounts: if account.username == uname and account.password == pword: self.logger.debug('found user {} in database'.format(uname)) res.write(c_uint8(0x01)) break elif account.banned: res.write(c_uint8(0x02)) break res.write(CString('Talk_Like_A_Pirate', allocated_length=33)) # unknown res.write(CString(allocated_length=33 * 7)) # unknown res.write(c_uint16(1)) # v. major res.write(c_uint16(10)) # v. current res.write(c_uint16(64)) # v. minor user_token = str(uuid.uuid4()) res.write(user_token[0:18], allocated_length=33) res.write(CString('127.0.0.1', allocated_length=33)) # world IP res.write(CString('127.0.0.1', allocated_length=33)) # chat IP res.write(c_uint16(2002)) # world port res.write(c_ushort(3003)) # chat port res.write(CString('0', allocated_length=33)) # unknown IP res.write( CString('00000000-0000-0000-0000-000000000000', allocated_length=37)) res.write(c_ulong(0)) res.write(CString('US', allocated_length=3)) # localization res.write(c_bool(False)) res.write(c_bool(False)) res.write(c_ulonglong(0)) res.write('error', length_type=c_uint16) # custom err msg res.write(c_uint16(0)) res.write(c_ulong(4)) return res
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 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)