示例#1
0
    def _send(self, player_indexes, translated_kwargs):
        """Send the user message to the given players.

        :param iterable player_indexes: All players with the same language
            setting.
        :param AttrDict translated_kwargs: The translated arguments.
        """
        recipients = RecipientFilter(*player_indexes)
        recipients.reliable = self.reliable
        user_message = UserMessage(recipients, self.message_name)

        if user_message.is_protobuf():
            self.protobuf(user_message.buffer, translated_kwargs)
            user_message.send()
        else:
            try:
                self.bitbuf(user_message.buffer, translated_kwargs)
            except:
                # In case of an error during writing to the buffer (e. g. by using
                # the wrong data type for the write_* methods) reset the buffer
                # and send the message. This causes the engine to silently ignore
                # the user message and the server doesn't crash upon creating
                # another user message.
                # See also:
                # https://github.com/Source-Python-Dev-Team/Source.Python/issues/315
                user_message.buffer.reset()

                # Re-raise the exception to make the user aware of the problem
                raise
            finally:
                user_message.send()
示例#2
0
    def send(self, *args, **kwargs):
        """Send the message to the given users."""
        # Get a recipient filter of the given users
        recipient = RecipientFilter(*(args or self.users))

        # Any parameter to translate?
        if self._translatable_parameters:

            # Get a default dictionnary to store the players
            languages = defaultdict(set)

            # Get a mapping of the given tokens
            tokens = ChainMap(kwargs, self.tokens)

            # Loop through all indexes
            for index in recipient:

                if playerinfo_from_index(index).is_fake_client():
                    continue

                # Add the current index
                languages[get_client_language(index)].add(index)

            # Loop through all languages
            for language, users in languages.items():

                # Get a dictionnary to store the translated strings
                translated_parameters = dict()

                # Loop through all translatable parameter
                for parameter_name in self._translatable_parameters:

                    # Get the current parameter value
                    parameter_value = self[parameter_name]

                    # Is the current parameter not translatable?
                    if not isinstance(parameter_value, TranslationStrings):

                        # No need to go further
                        continue

                    # Translate the current parameter
                    translated_parameters[
                        parameter_name] = parameter_value.get_string(
                        language, **tokens)

                # Update the recipient filter
                recipient.update(*users)

                # Send the message
                self._send_message(
                    recipient, **ChainMap(translated_parameters, self))

        # Otherwise
        else:

            # Send the message
            self._send_message(recipient, **self)
 def send(self, *player_indexes):
     """Send the user message."""
     # We need to handle the ShowMenu user message with bitbuffers
     # differently, because the maximum size is 255. If the message exceeds
     # this length, we need to sent it in several parts.
     if UserMessage.is_protobuf():
         recipients = RecipientFilter(*player_indexes)
         recipients.reliable = self.reliable
         user_message = UserMessage(recipients, self.message_name)
         self.protobuf(user_message.buffer, self)
         user_message.send()
     else:
         self.bitbuf(player_indexes, self)
示例#4
0
 def send(self, *player_indexes):
     """Send the user message."""
     # We need to handle the ShowMenu user message with bitbuffers
     # differently, because the maximum size is 255. If the message exceeds
     # this length, we need to sent it in several parts.
     if UserMessage.is_protobuf():
         recipients = RecipientFilter(*player_indexes)
         recipients.reliable = self.reliable
         user_message = UserMessage(recipients, self.message_name)
         self.protobuf(user_message.buffer, self)
         user_message.send()
     else:
         self.bitbuf(player_indexes, self)
示例#5
0
    def close(self, *ply_indexes):
        """Close the menu for the given player indexes.

        If no indexes were given, the menu will be closed for all players.
        """
        ply_indexes = RecipientFilter(*ply_indexes)
        for player_index in ply_indexes:
            queue = self.get_user_queue(player_index)

            # Try to remove this menu from the queue
            try:
                queue.remove(self)
            except ValueError:
                # If it fails, do nothing
                pass
            else:
                # If the queue is now empty, send an empty menu to hide
                # the last menu
                if not queue:
                    # Send an empty menu
                    self._close(player_index)

                else:
                    # There is at least one menu in the queue, so refresh to
                    # display it.
                    queue._refresh()
    def listener_on_entity_spawned(self, base_entity):
        if base_entity.classname != 'flashbang_projectile':
            return

        index = base_entity.index
        entity = Entity(index)

        for player in self._players:
            if player.inthandle == entity.owner_handle:
                break
        else:
            return

        temp_entity = TempEntity('BeamFollow')
        temp_entity.entity_index = index
        temp_entity.model_index = BEAM_MODEL.index
        temp_entity.halo_index = BEAM_MODEL.index
        temp_entity.life_time = 1
        temp_entity.start_width = 3
        temp_entity.end_width = 3
        temp_entity.fade_length = 1
        temp_entity.red = 255
        temp_entity.green = 255
        temp_entity.blue = 255
        temp_entity.alpha = 150

        temp_entity.create(RecipientFilter())
示例#7
0
    def listener_on_entity_spawned(self, index, base_entity):
        if base_entity.classname != 'flashbang_projectile':
            return

        entity = Entity(index)

        if entity.owner_handle not in (self.prisoner.inthandle,
                                       self.guard.inthandle):

            return

        temp_entity = TempEntity('BeamFollow')
        temp_entity.entity_index = index
        temp_entity.model_index = BEAM_MODEL.index
        temp_entity.halo_index = BEAM_MODEL.index
        temp_entity.life_time = 1
        temp_entity.start_width = 3
        temp_entity.end_width = 3
        temp_entity.fade_length = 1
        temp_entity.red = 255
        temp_entity.green = 255
        temp_entity.blue = 255
        temp_entity.alpha = 150

        temp_entity.create(RecipientFilter())
示例#8
0
    def _send(self, player_indexes, translated_kwargs):
        """Send the user message to the given players.

        :param iterable player_indexes: All players with the same language
            setting.
        :param AttrDict translated_kwargs: The translated arguments.
        """
        recipients = RecipientFilter(*player_indexes)
        recipients.reliable = self.reliable
        user_message = UserMessage(recipients, self.message_name)

        if user_message.is_protobuf():
            self.protobuf(user_message.buffer, translated_kwargs)
        else:
            self.bitbuf(user_message.buffer, translated_kwargs)

        user_message.send()
    def _send(self, player_indexes, translated_kwargs):
        """Send the user message to the given players.

        :param iterable player_indexes: All players with the same language
            setting.
        :param AttrDict translated_kwargs: The translated arguments.
        """
        recipients = RecipientFilter(*player_indexes)
        recipients.reliable = self.reliable
        user_message = UserMessage(recipients, self.message_name)

        if user_message.is_protobuf():
            self.protobuf(user_message.buffer, translated_kwargs)
        else:
            self.bitbuf(user_message.buffer, translated_kwargs)

        user_message.send()
 def _pre_user_message_begin(args):
     try:
         # Replace original recipients filter
         tmp_recipients = make_object(BaseRecipientFilter, args[1])
     except RuntimeError:
         # Patch for issue #314
         tmp_recipients = RecipientFilter.from_abstract_pointer(args[1])
     _recipients.update(*tuple(tmp_recipients), clear=True)
     args[1] = _recipients
示例#11
0
 def send(self, *player_indexes, **tokens):
     """Send the user message."""
     player_indexes = RecipientFilter(*player_indexes)
     for language, indexes in self._categorize_players_by_language(
             player_indexes).items():
         translated_kwargs = AttrDict(self)
         translated_kwargs.update(
             self._get_translated_kwargs(language, tokens))
         self._send(indexes, translated_kwargs)
示例#12
0
def pre_playback_temp_entity(stack_data):
    """Handle pre hooks."""
    temp_entity = TempEntity(stack_data[3])
    try:
        recipients = make_object(RecipientFilter, stack_data[1])
    except RuntimeError:
        global _recipients
        _recipients = RecipientFilter.from_abstract_pointer(stack_data[1])
        stack_data[1] = recipients = _recipients
    return temp_entity.template.handle_hook(temp_entity, recipients)
示例#13
0
    def send(self, *ply_indexes):
        """Send the menu to the given player indexes.

        If no indexes were given, the menu will be sent to every player.
        """
        ply_indexes = RecipientFilter(*ply_indexes)
        for player_index in ply_indexes:
            queue = self.get_user_queue(player_index)
            queue.append(self)
            queue._refresh()
    def bitbuf(self, player_indexes, kwargs):
        """Send the ShowMenu with bitbuf."""
        menu_string = kwargs.menu_string
        length = len(menu_string)
        recipients = RecipientFilter(*player_indexes)
        recipients.reliable = self.reliable
        while True:
            user_message = UserMessage(recipients, self.message_name)

            buffer = user_message.buffer
            buffer.write_word(kwargs.valid_slots)
            buffer.write_char(kwargs.display_time)
            buffer.write_byte(length > self.chunk_size)
            buffer.write_string(menu_string[:self.chunk_size])

            user_message.send()

            if length > self.chunk_size:
                menu_string = menu_string[self.chunk_size:]
                length -= self.chunk_size
            else:
                break
示例#15
0
    def bitbuf(self, player_indexes, kwargs):
        """Send the ShowMenu with bitbuf."""
        menu_string = kwargs.menu_string
        length = len(menu_string)
        recipients = RecipientFilter(*player_indexes)
        recipients.reliable = self.reliable
        while True:
            user_message = UserMessage(recipients, self.message_name)

            buffer = user_message.buffer
            buffer.write_word(kwargs.valid_slots)
            buffer.write_char(kwargs.display_time)
            buffer.write_byte(length > self.chunk_size)
            buffer.write_string(menu_string[:self.chunk_size])

            user_message.send()

            if length > self.chunk_size:
                menu_string = menu_string[self.chunk_size:]
                length -= self.chunk_size
            else:
                break
示例#16
0
    def __call__(self, recipients=None, *args, **kwargs):
        """Sends the effect."""
        recipients = RecipientFilter() if recipients is None else recipients
        arguments = self.args.copy()
        _update_ordered_dict(arguments, args, kwargs)

        # Update model's path to the model's index
        model = arguments.get('model')
        if model and isinstance(model, str):
            arguments['model'] = _model_indexes[model]

        # Call the function
        self.function(recipients, *arguments.values())
示例#17
0
 def _pre_user_message_begin(args):
     try:
         # Replace original recipients filter
         tmp_recipients = make_object(BaseRecipientFilter, args[1])
         _recipients.update(*tuple(tmp_recipients), clear=True)
     except RuntimeError:
         # Patch for issue #314
         tmp_recipients = RecipientFilter()
         (args[1] + 4).copy(
             get_object_pointer(tmp_recipients) + 4,
             get_size(RecipientFilter) - 4)
         _recipients.update(*tuple(tmp_recipients), clear=True)
     args[1] = _recipients
    def _pre_send_user_message(args):
        message_index = args[2]

        user_message_hooks = HookUserMessage.hooks[message_index]
        protobuf_user_message_hooks = HookProtobufUserMessage.hooks[
            message_index]

        # No need to do anything behind this if no listener is registered
        if not user_message_hooks and not protobuf_user_message_hooks:
            return

        try:
            # Replace original recipients filter
            tmp_recipients = make_object(BaseRecipientFilter, args[1])
        except RuntimeError:
            # Patch for issue #314
            tmp_recipients = RecipientFilter.from_abstract_pointer(args[1])
        _recipients.update(*tuple(tmp_recipients), clear=True)
        args[1] = _recipients

        try:
            buffer = make_object(ProtobufMessage, args[3])
            wrapped_from_abstract = False
        except RuntimeError:
            # Patch for issue #390 - UserMessage was created by another plugin.
            buffer = ProtobufMessage.from_abstract_pointer(args[3])
            wrapped_from_abstract = True

        protobuf_user_message_hooks.notify(_recipients, buffer)

        # No need to do anything behind this if no listener is registered
        if user_message_hooks:
            try:
                impl = get_user_message_impl(message_index)
            except NotImplementedError:
                impl = None

            if impl is not None:
                data = impl.read(buffer)
                user_message_hooks.notify(_recipients, data)

                # Update buffer if data has been changed
                if data.has_been_changed():
                    buffer.clear()
                    impl.write(buffer, data)

        # If we wrapped the buffer from an abstract pointer, make sure to
        #   apply any changes that may have been made back into the original.
        if wrapped_from_abstract:
            buffer.parse_to_abstract_pointer(args[3])
示例#19
0
    def play(self, *recipients):
        """Play the sound."""
        # Get the recipients to play the sound to
        recipients = RecipientFilter(*recipients)

        # Is the sound precached?
        if not self.is_precached:

            # Precache the sound
            self.precache()

        # Play the sound
        engine_sound.emit_sound(
            recipients, self.index, self.channel, self.sample,
            self.volume, self.attenuation, self.flags, self.pitch,
            self.origin, self.direction, self.origins,
            self.update_positions, self.sound_time, self.speaker_entity)
示例#20
0
    def _pre_send_user_message(args):
        message_index = args[2]

        user_message_hooks = HookUserMessage.hooks[message_index]
        protobuf_user_message_hooks = HookProtobufUserMessage.hooks[
            message_index]

        # No need to do anything behind this if no listener is registered
        if not user_message_hooks and not protobuf_user_message_hooks:
            return

        try:
            # Replace original recipients filter
            tmp_recipients = make_object(BaseRecipientFilter, args[1])
            _recipients.update(*tuple(tmp_recipients), clear=True)
        except RuntimeError:
            # Patch for issue #314
            tmp_recipients = RecipientFilter()
            (args[1] + 4).copy(
                get_object_pointer(tmp_recipients) + 4,
                get_size(RecipientFilter) - 4)
            _recipients.update(*tuple(tmp_recipients), clear=True)
        args[1] = _recipients

        buffer = make_object(ProtobufMessage, args[3])

        protobuf_user_message_hooks.notify(_recipients, buffer)

        # No need to do anything behind this if no listener is registered
        if not user_message_hooks:
            return

        try:
            impl = get_user_message_impl(message_index)
        except NotImplementedError:
            return

        data = impl.read(buffer)
        user_message_hooks.notify(_recipients, data)

        # Update buffer if data has been changed
        if data.has_been_changed():
            buffer.clear()
            impl.write(buffer, data)
示例#21
0
    def send(self, *player_indexes, **tokens):
        """Send the Dialog message to the appropriate recipients.

        :param player_indexes: Values can be a player index, multiple player
            indexes (star args),
            a :class:`filters.players.PlayerIter` instance,
            or a :class:`filters.recipients.RecipientFilter` instance.
        :param tokens: Keyword arguments used to replace values in messages.
        """
        # Get a recipient filter of the given users
        recipients = RecipientFilter(*player_indexes)

        # Get the KeyValues instance
        keyvalues = KeyValues(self.message_type.name.lower())

        # Set the time for the message to display
        keyvalues.set_int('time', self.time)

        # Loop through all recipients
        for index in recipients:

            # Get a Player instance for the current player
            player = Player(index)

            # Is the player not human?
            if player.is_fake_client():
                continue

            # Get the level for the message
            level = self._get_player_level(player.userid)

            # Set the level for the player
            keyvalues.set_int('level', level)

            # Set the title (value should be server IP address)
            keyvalues.set_string(
                'title', self._get_text(self.title, player, **tokens))

            # Set any remaining keyvalues
            self._set_keyvalues(keyvalues, player, **tokens)

            # Send the message
            create_message(player.edict, self.message_type, keyvalues)
示例#22
0
    def play(self, *recipients):
        """Play the sound.

        :param recipients:
            Players who will hear the sound.
        """
        # Done here to fix a cyclic import...
        from filters.recipients import RecipientFilter

        # Get the recipients to play the sound to
        recipients = RecipientFilter(*recipients)

        # Is the sound precached?
        if not self.is_precached:

            # Precache the sound
            self.precache()

        # Play the sound
        self._play(recipients)
示例#23
0
    def create(self, *recipients, delay=0.0, **aliases):
        """Create the temp entity effect.

        :param RecipientFilter recipients:
            The recipient filter listing the players to send the effect to.
        :param float delay:
            The delay before creating the effect.
        :param dict aliases:
            Any aliases to set before creating the temp entity effect.
        """
        # Get a recipient filter matching the given players...
        recipients = RecipientFilter(*recipients)

        # Loop trhough all given aliases...
        for alias, value in aliases.items():

            # Set the alias to the given value...
            setattr(self, alias, value)

        # Create the temp entity effect...
        super().create(recipients, delay)
    def tick(self):
        for index, (attach_to, start_vector) in self.items():
            if attach_to == VectorAttachTo.VIEW_COORDINATES:
                end_vector = players[index].view_coordinates
            else:
                end_vector = players[index].origin

            if end_vector is None:
                return

            round_vector(end_vector, EDITOR_STEP_UNITS)

            box(RecipientFilter(index),
                start_vector,
                end_vector,
                color=EDITOR_LINE_COLOR,
                life_time=TICK_REPEAT_INTERVAL,
                halo=EDITOR_LINE_MODEL,
                model=EDITOR_LINE_MODEL,
                start_width=EDITOR_LINE_WIDTH,
                end_width=EDITOR_LINE_WIDTH)
    def send(self, userid):
        msg_index = get_message_index(self.name)
        if msg_index == -1:
            import es
            dbgmsg(0, 'Invalid UserMessage type: {}'.format(self.name))
            return

        try:
            index = index_from_userid(atoi(userid))
        except ValueError:
            return

        # We need to save the RecipientFilter instance here. Otherwise it would
        # get garbage collected before it is send.
        recipients = RecipientFilter(index)
        user_message = UserMessage(recipients, self.name)
        buffer = user_message.buffer

        for type_name, value in self:
            self._write(buffer, type_name, value)

        user_message.send()
示例#26
0
    def send(self, *ply_indexes, **tokens):
        """Send the menu to the given player indexes.

        If no indexes were given, the menu will be sent to every player.

        :param ply_indexes:
            Player indexes that should receive the menu.
        :param tokens:
            Translation tokens for menu options, title and description.
        """
        ply_indexes = tuple(RecipientFilter(*ply_indexes))
        if not ply_indexes:
            return

        # Update option tokens
        for option in self:
            try:
                option.text.tokens.update(**tokens)
            except AttributeError:
                # Not a _MenuData or TranslationStrings instance
                pass

        # Update title if existant
        try:
            self.title.tokens.update(**tokens)
        except AttributeError:
            pass

        # Update description if existant
        try:
            self.description.tokens.update(**tokens)
        except AttributeError:
            pass

        for player_index in ply_indexes:
            queue = self.get_user_queue(player_index)
            queue.append(self)
            queue._refresh()
 def append_zone(self):
     recipients = RecipientFilter()
     recipients.remove_all_players()
     self.append(recipients)
# =============================================================================
# >> ALL DECLARATION
# =============================================================================
__all__ = (
    'HookUserMessageBase',
    'HookBitBufferUserMessage',
    'HookProtobufUserMessage',
    'HookUserMessage',
)

# =============================================================================
# >> GLOBAL VARIABLES
# =============================================================================
_user_message_data = None
_recipients = RecipientFilter()


# =============================================================================
# >> CLASSES
# =============================================================================
class HookUserMessageBase(AutoUnload):
    """Base decorator for user message hooks."""
    def __init__(self, user_message):
        """Create a new user message hook.

        :param int/str user_message:
            The user message index or name to hook.
        :raise TypeError:
            Raised if ``user_message`` is not and int or str.
        :raise ValueError: