def append_other_data(self, datagram): field_packer = DCPacker() for index in self._other_fields: field = self._dc_class.get_field_by_index(index) if not field: self.notify.error( 'Failed to append other data for field: %s dclass: %s, unknown field!' % (field_name, self._dc_class.get_name())) field_packer.begin_pack(field) field.pack_args(field_packer, self._other_fields[field.get_number()]) field_packer.end_pack() datagram.append_data(field_packer.get_string())
def handle_send_update(self, field, sender, channel, di): datagram = io.NetworkDatagram() datagram.add_header(channel, sender, types.STATESERVER_OBJECT_UPDATE_FIELD) datagram.add_uint32(self._do_id) datagram.add_uint16(field.get_number()) field_packer = DCPacker() field_packer.begin_pack(field) if di.get_remaining_size(): field_packer.pack_literal_value(di.get_remaining_bytes()) field_packer.end_pack() datagram.append_data(field_packer.get_string()) self._network.handle_send_connection_datagram(datagram)
def create_object(self, channel_id, database_id, dclass, fields={}, callback=None): """ Create an object in the specified database. database_id specifies the control channel of the target database. dclass specifies the class of the object to be created. fields is a dict with any fields that should be stored in the object on creation. callback will be called with callback(do_id) if specified. On failure, do_id is 0. """ # Save the callback: ctx = self.get_context() self._callbacks[ctx] = callback # Pack up/count valid fields. field_packer = DCPacker() field_count = 0 for k, v in fields.items(): field = dclass.get_field_by_name(k) if not field: self.notify.error( 'Creation request for %s object contains an invalid field named %s' % (dclass.get_name(), k)) field_packer.raw_pack_uint16(field.get_number()) field_packer.begin_pack(field) field.pack_args(field_packer, v) field_packer.end_pack() field_count += 1 # Now generate and send the datagram: dg = NetworkDatagram() dg.add_header(database_id, channel_id, types.DBSERVER_CREATE_OBJECT) dg.add_uint32(ctx) dg.add_uint16(dclass.get_number()) dg.add_uint16(field_count) dg.append_data(field_packer.get_string()) self._network.handle_send_connection_datagram(dg)
def handle_object_get_all(self, sender, di): context = di.get_uint32() do_id = di.get_uint32() file_object = self._backend.open_file( self._backend.get_filename(do_id)) if not file_object: self.notify.warning( 'Failed to get fields for object: %d context: %d, unknown object!' % (do_id, context)) return dc_name = file_object.get_value('dclass') dc_class = self.dc_loader.dclasses_by_name.get(dc_name) if not dc_class: self.notify.warning( 'Failed to query object: %d context: %d, unknown dclass: %s!' % (do_id, context, dc_name)) return fields = file_object.get_value('fields') if not fields: self.notify.warning( 'Failed to query object: %d context %d, invalid fields!' % (do_id, context)) return datagram = io.NetworkDatagram() datagram.add_header(sender, self.channel, types.DBSERVER_OBJECT_GET_ALL_RESP) datagram.add_uint32(context) datagram.add_uint8(1) field_packer = DCPacker() field_count = 0 for field_name, field_args in fields.items(): field = dc_class.get_field_by_name(field_name) if not field: self.notify.warning( 'Failed to query object %d context: %d, unknown field: %s' % (do_id, context, field_name)) return field_packer.raw_pack_uint16(field.get_number()) field_packer.begin_pack(field) field.pack_args(field_packer, field_args) field_packer.end_pack() field_count += 1 self._backend.close_file(file_object) datagram.add_uint16(dc_class.get_number()) datagram.add_uint16(field_count) datagram.append_data(field_packer.get_string()) self.handle_send_connection_datagram(datagram)