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)
Esempio n. 3
0
    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)
Esempio n. 4
0
    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)