def test_initialization(self): dg = Datagram(b'\x01\x02\x03') self.assertEqual(dg.bytes(), b'\x01\x02\x03') random.seed('test_initialization') data = os.urandom(32) dg = Datagram(data) self.assertEqual(dg.bytes(), data)
def test_add_datagram(self): dg1 = Datagram() dg1.add_uint16(32) dg2 = Datagram() dg2.add_string16(b'hello') dg1.add_datagram(dg2) self.assertEqual(dg1.bytes(), struct.pack('<HH5B', 32, 5, *b'hello')) del dg2 self.assertEqual(dg1.bytes(), struct.pack('<HH5B', 32, 5, *b'hello'))
def test_copy_datagram(self): dg = Datagram() dg.add_string32('testing copy'.encode('utf-8')) dg2 = dg.copy() self.assertEqual(dg.bytes(), dg2.bytes()) dg.add_uint16(65200) self.assertNotEqual(dg.bytes(), dg2.bytes()) data = dg2.bytes() del dg self.assertEqual(dg2.bytes(), data)
def generate_hash(self, hash_gen): hash_gen.add_string(self.identifier) self.dtype.generate_hash(hash_gen) hash_gen.add_int(len(self.cases)) for case in self.cases: try: dg = Datagram() pack_functions[DCTypes[self.dtype]](dg, case.value) except KeyError: dg = Datagram() self.dtype.pack_value(dg, case.value) hash_gen.add_bytes(dg.bytes()) hash_gen.add_int(len(case.parameters) + 1) self.dtype.generate_hash(hash_gen) for parameter in case.parameters: parameter.generate_hash(hash_gen) if self.default_case is not None: hash_gen.add_int(len(self.default_case.parameters) + 1) self.dtype.generate_hash(hash_gen) for parameter in self.default_case.parameters: parameter.generate_hash(hash_gen)
def test_add_uint32(self): dg = Datagram() dg.add_uint32(1 << 31) other = struct.pack('<I', 1 << 31) self.assertEqual(dg.bytes(), other) with self.assertRaises(OverflowError): dg.add_uint32(1 << 32)
def test_add_int8(self): dg = Datagram() dg.add_int8(-127) dg.add_int8(127) other = struct.pack('<bb', -127, 127) self.assertEqual(dg.bytes(), other) with self.assertRaises(OverflowError): dg.add_int8(-128) dg.add_int8(128)
def disconnect(self, booted_index, booted_text): for task in self.tasks: task.cancel() del self.tasks[:] resp = Datagram() resp.add_uint16(CLIENT_GO_GET_LOST) resp.add_uint16(booted_index) resp.add_string16(booted_text.encode('utf-8')) self.transport.write(len(resp).to_bytes(2, byteorder='little')) self.transport.write(resp.bytes()) self.transport.close() self.service.log.debug( f'Booted client {self.channel} with index {booted_index} and text: "{booted_text}"' )
def test_add_uint8(self): dg = Datagram() other = b'' dg.add_uint8(12) other += pack_unsigned(12) self.assertEqual(dg.bytes(), other) dg.add_uint8(47) other += pack_unsigned(47) self.assertEqual(dg.bytes(), other) dg.add_uint8(255) other += pack_unsigned(255) self.assertEqual(dg.bytes(), other) dg.add_uint8(0) other += pack_unsigned(0) self.assertEqual(dg.bytes(), other) with self.assertRaises(OverflowError): dg.add_uint8(256) dg.add_uint8(-3)
def test_add_data(self): s = 'hello_world'.encode('utf-8') dg = Datagram() dg.add_string16(s) other = struct.pack(f'<H{len(s)}b', len(s), *s) self.assertEqual(dg.bytes(), other) s = 'abcdefghijklmnop'.encode('utf-8') dg = Datagram() dg.add_string32(s) other = struct.pack(f'<I{len(s)}b', len(s), *s) self.assertEqual(dg.bytes(), other) dg.add_bytes(b'') self.assertEqual(dg.bytes(), other) dg = Datagram() dg.add_string16(b'') self.assertEqual(dg.bytes(), b'\x00\x00') dg = Datagram() random.seed('pydc') s = bytes(random.randint(0, 255) for _ in range((1 << 16))) with self.assertRaises(OverflowError): dg.add_string16(s) dg = Datagram() s = bytes(random.randint(0, 255) for _ in range((1 << 16))) dg.add_string32(s) s = b''.join((struct.pack('<I', len(s)), s)) self.assertEqual(dg.bytes(), s) dg = Datagram() dg.add_string32(b'') self.assertEqual(dg.bytes(), struct.pack('<I', 0)) dg = Datagram() c = chr(0x1F600).encode('utf-8') dg.add_bytes(c) self.assertEqual(dg.bytes(), c)
async def create_toon(self, sender, context, dclass, disl_id, pos, fields): try: do_id = await self.backend.create_object(dclass, fields) account = await self.backend.query_object_fields(disl_id, ['ACCOUNT_AV_SET'], 'Account') temp = Datagram() temp.add_bytes(account['ACCOUNT_AV_SET']) av_set = self.dc.namespace['Account']['ACCOUNT_AV_SET'].unpack_value(temp.iterator()) print(do_id, disl_id, pos, av_set) av_set[pos] = do_id temp.seek(0) self.dc.namespace['Account']['ACCOUNT_AV_SET'].pack_value(temp, av_set) await self.backend.set_field(disl_id, 'ACCOUNT_AV_SET', temp.bytes(), 'Account') except OTPCreateFailed as e: print('creation failed', e) do_id = 0 dg = Datagram() dg.add_server_header([sender], DBSERVERS_CHANNEL, DBSERVER_CREATE_STORED_OBJECT_RESP) dg.add_uint32(context) dg.add_uint8(do_id == 0) dg.add_uint32(do_id) self.send_datagram(dg)
def append_other_data(self, dg, client_only, also_owner): if client_only: fields_dg = Datagram() count = 0 for field_name, raw_data in self.ram.items(): field = self.dclass.fields_by_name[field_name] if field.is_broadcast or field.is_clrecv or (also_owner and field.is_ownrecv): fields_dg.add_uint16(field.number) fields_dg.add_bytes(raw_data) count += 1 dg.add_uint16(count) if count: dg.add_bytes(fields_dg.bytes()) else: dg.add_uint16(len(self.ram)) for field_name, raw_data in self.ram.items(): field = self.dclass.fields_by_name[field_name] dg.add_uint16(field.number) dg.add_bytes(raw_data)
def makeNetString(self): dg = Datagram() dg.add_bytes(self.type.encode('ascii')) if self.type == 't': dg.add_uint8(toonHeadTypes.index(self.head)) dg.add_uint8(toonTorsoTypes.index(self.torso)) dg.add_uint8(toonLegTypes.index(self.legs)) if self.gender == 'm': dg.add_uint8(1) else: dg.add_uint8(0) dg.add_uint8(self.topTex) dg.add_uint8(self.topTexColor) dg.add_uint8(self.sleeveTex) dg.add_uint8(self.sleeveTexColor) dg.add_uint8(self.botTex) dg.add_uint8(self.botTexColor) dg.add_uint8(self.armColor) dg.add_uint8(self.gloveColor) dg.add_uint8(self.legColor) dg.add_uint8(self.headColor) else: raise Exception(f'unknown avatar type: {self.type}') return dg.bytes()
def send_datagram(self, data: Datagram): loop = self.service.loop loop.call_soon_threadsafe(self.outgoing_q.put_nowait, data.bytes())
def send_datagram(self, data: Datagram): self.outgoing_q.put_nowait(data.bytes())