def _hook_set_client_listening(cls):
        if cls._set_client_listening is not None:
            return

        function = get_virtual_function(voice_server, 'SetClientListening')
        function.add_hook(HookType.PRE, _pre_set_client_listening)

        cls._set_client_listening = function

        on_client_disconnect_listener_manager.register_listener(
            _on_client_disconnect)
Exemple #2
0
    def __init__(self, temp_entity_name):
        """Initialize the hook object.

        :param str temp_entity_name: The name of the temp entity to hook.
        """
        # Store the given temp entity name...
        self.name = temp_entity_name

        # Store the function to hook...
        self.function = get_virtual_function(
            temp_entity_templates[temp_entity_name], 'Create')

        # Set the callback to None...
        self._callback = None
Exemple #3
0
    def __init__(self, temp_entity_name):
        """Initialize the hook object.

        :param str temp_entity_name: The name of the temp entity to hook.
        """
        # Store the given temp entity name...
        self.name = temp_entity_name

        # Store the function to hook...
        self.function = get_virtual_function(
            temp_entity_templates[temp_entity_name], 'Create')

        # Set the callback to None...
        self._callback = None
Exemple #4
0
    def __init__(self, temp_entity_name):
        """Initialize the hook object.

        :param str temp_entity_name: The name of the temp entity to hook.
        """
        # Store the given temp entity name...
        self.name = temp_entity_name

        # Set the callback to None...
        self._callback = None

        try:
            # Store the function to hook...
            self.function = get_virtual_function(
                temp_entity_templates[temp_entity_name], 'Create')
        except NameError:
            # Given name was invalid, set the function to None...
            self.function = None

            # Re-raise the error...
            raise
Exemple #5
0
    def __init__(self, temp_entity_name):
        """Initialize the hook object.

        :param str temp_entity_name:
            The name of the temp entity to hook.
        """
        # Store the given temp entity name...
        self.name = temp_entity_name

        # Set the callback to None...
        self._callback = None

        try:
            # Store the function to hook...
            self.function = get_virtual_function(
                temp_entity_templates[temp_entity_name], 'Create')
        except NameError:
            # Given name was invalid, set the function to None...
            self.function = None

            # Re-raise the error...
            raise

# ============================================================================
# >> Fix for issue #181.
# ============================================================================
# Get the function name to hook...
if SOURCE_ENGINE in ('bms', 'orangebox', 'gmod'):
    _hibernation_function_name = 'SetServerHibernation'
elif SOURCE_ENGINE in ('blade', 'csgo', 'l4d2'):
    _hibernation_function_name = 'ServerHibernationUpdate'
else:
    # To remind us to add newly supported engines...
    raise NotImplementedError('No hibernation function exposed.')


@PreHook(get_virtual_function(server_game_dll, _hibernation_function_name))
def _pre_hibernation_function(stack_data):
    """Called when the server is hibernating."""
    if not stack_data[1]:
        return

    # Disconnect all bots...
    _disconnect_bots()


@OnLevelEnd
def _on_level_end():
    """Disconnect all bots on level end."""
    _disconnect_bots()

Exemple #7
0
# =============================================================================
@OnLevelInit
def _on_level_init(map_name):
    """Called when a new map gets initialized."""
    if not _check_for_update.get_int():
        return

    try:
        update_available, version = is_newer_version_available()
    except (URLError, socket.timeout):
        return

    if not update_available:
        return

    if _notify_on_update.get_int():
        # TODO: Add translations
        listeners_logger.log_warning(
            'A new Source.Python version is available!')

    on_version_update_listener_manager.notify(VERSION, version,
                                              is_unversioned())


@PreHook(memory.get_virtual_function(cvar, 'CallGlobalChangeCallbacks'))
def _pre_call_global_change_callbacks(args):
    """Called when a ConVar has been changed."""
    convar = memory.make_object(ConVar, args[1])
    old_value = args[2]
    on_convar_changed_listener_manager.notify(convar, old_value)
mapcycle_json = None

# Delays
delay_scheduled_vote = None
delay_changelevel = None
delay_end_vote = None
delay_likemap_survey = None

# Popups
nomination_popup = PagedMenu(title=popups_strings['nominate_map'])
likemap_popup = SimpleMenu()
main_popup = PagedMenu(title=popups_strings['choose_map'])

# ChangeLevel function (to hook)
engine_server_changelevel = get_virtual_function(engine_server, 'ChangeLevel')


# =============================================================================
# >> CLASSES
# =============================================================================
class CorruptJSONFile(Exception):
    """Raised when mapcycle.json doesn't contain a list."""
    pass


# =============================================================================
# >> SYNCHRONOUS DATABASE OPERATIONS
# =============================================================================
Base.metadata.create_all(engine)
    user_manager.create(player)


@OnClientDisconnect
def listener_on_client_disconnect(index):
    if index in user_manager:
        user_manager.delete(index)

    if status.vote_status == status.VoteStatus.NOT_STARTED:
        check_if_enough_rtv()

    elif status.vote_status == status.VoteStatus.IN_PROGRESS:
        check_if_enough_votes()


engine_server_changelevel = get_virtual_function(engine_server, 'ChangeLevel')


@PreHook(engine_server_changelevel)
def hook_on_pre_change_level(args):
    log.log_debug("Hooked ChangeLevel...")

    # Set our own next map
    if status.next_map is not None:
        args[1] = status.next_map.filename


@ServerCommand(ANTI_SPAM_TIMEOUT_SERVER, 'mc')
def command_on_mc(command):
    current_command = mc_commands['mc']
    i = 0
Exemple #10
0
        # Is the callback in the list?
        if callback not in self:

            # If not, raise an error
            raise ValueError(
                'Pre-Event callback "{0}" is not registered for '
                'event "{1}"'.format(callback, self.event_name))

        # Remove the callback from the list
        super().remove(callback)


# =============================================================================
# >> PRE-HOOK FUNCTIONS
# =============================================================================
@PreHook(get_virtual_function(game_event_manager, 'FireEvent'))
def _pre_game_event(args):
    """Call pre-event functions if the event is registered."""
    # Get the GameEvent object
    game_event = make_object(GameEvent, args[1])

    # Get the name of the event
    event_name = game_event.name

    # If the current event is not in the dictionary, return
    if event_name not in pre_event_manager:
        return

    # Create a variable to know what to do after all pre-events are called
    event_action = EventAction.CONTINUE
Exemple #11
0
        """
        from weapons.restrictions import weapon_restriction_manager
        return weapon_restriction_manager.is_player_restricted(self, weapon)

    @property
    def spectators(self):
        """Return all players observing this player.

        :return: The generator yields :class:`players.entity.Player` objects.
        :rtype: generator
        """
        from filters.players import PlayerIter
        for other in PlayerIter('dead'):
            if self.inthandle == other.observer_target:
                yield other


# =============================================================================
# >> CALLBACKS
# =============================================================================
if SOURCE_ENGINE_BRANCH in ('css', 'csgo'):

    @PreHook(memory.get_virtual_function(engine_server, 'ClientCommand'))
    def _pre_client_command(args):
        """Block name changes started by the server.

        Pre-hook on IVEngineServer::ClientCommand to block the name changes.
        """
        if args[2] == 'name "%s"':
            return 0
Exemple #12
0
# This file is part of ArcJail.
#
# ArcJail is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# ArcJail is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with ArcJail.  If not, see <http://www.gnu.org/licenses/>.

from engines.server import server_game_dll

from memory import get_virtual_function
from memory.hooks import PreHook

from ..info import info


ARCJAIL_DESCRIPTION = "{} {}".format(info.name, info.version)


@PreHook(get_virtual_function(server_game_dll, 'GetGameDescription'))
def pre_get_game_description(args):
    return ARCJAIL_DESCRIPTION
Exemple #13
0
        # Unregister the hook...
        self.template.remove_hook(self.callback)


class TempEntityPostHook(TempEntityPreHook):
    """Decorator used to create temp entity post hooks that auto unload."""
    def __init__(self, temp_entity_name):
        """Initialize the hook object.

        :param str temp_entity_name:
            The name of the temp entity to hook.
        """
        from warnings import warn
        warn('TempEntityPostHook has been deprecated and will be entirely '
             'unsupported in a future update. Use TempEntityPreHook instead '
             'or register your own post hook on '
             'CEngineServer::PlaybackTempEntity/CBaseTempEntity::Create.')

        super().__init__(temp_entity_name)


# =============================================================================
# >> HOOKS
# =============================================================================
@PreHook(get_virtual_function(engine_server, 'PlaybackTempEntity'))
def pre_playback_temp_entity(stack_data):
    """Handle pre hooks."""
    temp_entity = TempEntity(stack_data[3])
    return temp_entity.template.handle_hook(
        temp_entity, make_object(RecipientFilter, stack_data[1]))
            Source.Python.

        .. seealso:: :meth:`HookUserMessageBase.__init__`
        """
        super().__init__(user_message)

        # Verify that the user message is supported/implemented. This will
        # raise a NotImplementedError if it isn't.
        self.impl = get_user_message_impl(self.message_index)


# =============================================================================
# >> HOOKS
# =============================================================================
if UserMessage.is_protobuf():
    @PreHook(get_virtual_function(engine_server, 'SendUserMessage'))
    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

        # Replace original recipients filter
        tmp_recipients = make_object(BaseRecipientFilter, args[1])
        _recipients.update(*tuple(tmp_recipients), clear=True)
        args[1] = _recipients
        .. seealso:: :meth:`HookUserMessageBase.__init__`
        """
        super().__init__(user_message)

        # Verify that the user message is supported/implemented. This will
        # raise a NotImplementedError if it isn't.
        self.impl = get_user_message_impl(self.message_index)


# =============================================================================
# >> HOOKS
# =============================================================================
if UserMessage.is_protobuf():

    @PreHook(get_virtual_function(engine_server, 'SendUserMessage'))
    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:
Exemple #16
0
    if _notify_on_update.get_int():
        # TODO: Add translations
        listeners_logger.log_warning(
            'A new Source.Python version is available!')

    on_version_update_listener_manager.notify(
        VERSION, version, is_unversioned())


@OnLevelShutdown
def _on_level_shutdown():
    """Called on level end."""
    # Was no map initialized?
    if not OnLevelEnd._level_initialized:
        return

    # Notify all registred callbacks
    on_map_end_listener_manager.notify()

    # Make sure we don't get called more than once per map change
    OnLevelEnd._level_initialized = False


@PreHook(memory.get_virtual_function(cvar, 'CallGlobalChangeCallbacks'))
def _pre_call_global_change_callbacks(args):
    """Called when a ConVar has been changed."""
    convar = memory.make_object(ConVar, args[1])
    old_value = args[2]
    on_convar_changed_listener_manager.notify(convar, old_value)
Exemple #17
0
        If you want to check if the player is muted only for specific players,
        pass a tuple that contains the player indexes that should be checked.
        """
        return all(map(
            lambda receiver: sender in self[receiver],
            self._get_receivers(receivers)))

# The singleton object of the :class:`_MuteManager` class
mute_manager = _MuteManager(set)


# =============================================================================
# >> CALLBACKS
# =============================================================================
@PreHook(memory.get_virtual_function(voice_server, 'SetClientListening'))
def _pre_set_client_listening(args):
    """Called before IVoiceServer::SetClientListening is called."""
    receiver = args[1]
    sender = args[2]

    # Check if the sender is muted for this receiver
    if mute_manager.is_muted(sender, [receiver]):
        args[3] = False


@OnClientDisconnect
def _on_client_disconnect(index):
    """Called when a player left the server."""
    # Unmute the player, so the next player who gets this index won't be muted
    mute_manager.unmute_player(index)
Exemple #18
0
@OnLevelShutdown
def _on_level_shutdown():
    """Called on level end."""
    # Was no map initialized?
    if not OnLevelEnd._level_initialized:
        return

    # Notify all registred callbacks
    on_level_end_listener_manager.notify()

    # Make sure we don't get called more than once per map change
    OnLevelEnd._level_initialized = False


@PreHook(get_virtual_function(cvar, 'CallGlobalChangeCallbacks'))
def _pre_call_global_change_callbacks(args):
    """Called when a ConVar has been changed."""
    convar = make_object(ConVar, args[1])
    old_value = args[2]
    on_convar_changed_listener_manager.notify(convar, old_value)


def _pre_fire_output(args):
    """Called when an output is about to be fired."""
    if not on_entity_output_listener_manager:
        return

    # Windows is a bit weird: the function takes 4 additional arguments...
    if PLATFORM == 'windows':
        args = (args[0], ) + tuple(args)[5:]
Exemple #19
0
        """
        engine_server.server_command("kickid {} {}".format(self.userid, message).rstrip())

    def ban(self, duration=0, kick=True, write_ban=True):
        """Ban a player from the server.

        :param int duration: Duration of the ban in minutes. Use 0 for
            permament.
        :param bool kick: If True, the player will be kicked as well.
        :param bool write_ban: If True, the ban will be written to
            ``cfg/banned_users.cfg``.
        """
        engine_server.server_command("banid {} {} {}".format(duration, self.userid, "kick" if kick else ""))
        if write_ban:
            engine_server.server_command("writeid")


# =============================================================================
# >> CALLBACKS
# =============================================================================
if SOURCE_ENGINE_BRANCH in ("css", "csgo"):

    @PreHook(memory.get_virtual_function(engine_server, "ClientCommand"))
    def _pre_client_command(args):
        """Block name changes started by the server.

        Pre-hook on IVEngineServer::ClientCommand to block the name changes.
        """
        if args[2] == 'name "%s"':
            return 0
Exemple #20
0
@OnLevelShutdown
def _on_level_shutdown():
    """Called on level end."""
    # Was no map initialized?
    if not OnLevelEnd._level_initialized:
        return

    # Notify all registred callbacks
    on_level_end_listener_manager.notify()

    # Make sure we don't get called more than once per map change
    OnLevelEnd._level_initialized = False


@PreHook(get_virtual_function(cvar, 'CallGlobalChangeCallbacks'))
def _pre_call_global_change_callbacks(args):
    """Called when a ConVar has been changed."""
    convar = make_object(ConVar, args[1])
    old_value = args[2]
    on_convar_changed_listener_manager.notify(convar, old_value)


# ============================================================================
# >> Fix for issue #181.
# ============================================================================
# Get the function name to hook...
if SOURCE_ENGINE in ('bms', 'orangebox'):
    _hibernation_function_name = 'SetServerHibernation'
elif SOURCE_ENGINE in ('blade', 'csgo', 'l4d2'):
    _hibernation_function_name = 'ServerHibernationUpdate'
Exemple #21
0
# This file is part of ArcJail.
#
# ArcJail is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# ArcJail is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with ArcJail.  If not, see <http://www.gnu.org/licenses/>.

from engines.server import server_game_dll

from memory import get_virtual_function
from memory.hooks import PreHook

from ..info import info

ARCJAIL_DESCRIPTION = "{} {}".format(info.name, info.version)


@PreHook(get_virtual_function(server_game_dll, 'GetGameDescription'))
def pre_get_game_description(args):
    return ARCJAIL_DESCRIPTION
        :param bool force:
            Whether or not the spawn should be forced.
        """
        # Is the player spawnable?
        if not force and (self.team <= 1 or not self.dead):
            return

        # Spawn the player...
        self._spawn()

    @wrap_entity_mem_func
    def give_named_item(self, item, sub_type=0, econ_item_view=None, unk=False, unk2=NULL):
        """Give the player a named item."""
        # TODO: What's the unk argument for?
        # unk2 is a Vector (position)? Should do some tests...
        return [item, sub_type, econ_item_view, unk, unk2]


# =============================================================================
# >> CALLBACKS
# =============================================================================
@PreHook(get_virtual_function(engine_server, 'ClientCommand'))
def _pre_client_command(args):
    """Block name changes started by the server.

    Pre-hook on IVEngineServer::ClientCommand to block the name changes.
    """
    if args[2] == 'name "%s"':
        return 0
Exemple #23
0
        # Is the callback in the list?
        if callback not in self:

            # If not, raise an error
            raise ValueError(
                'Pre-Event callback "{0}" is not registered for '
                'event "{1}"'.format(callback, self.event_name))

        # Remove the callback from the list
        super().remove(callback)


# =============================================================================
# >> PRE-HOOK FUNCTIONS
# =============================================================================
@PreHook(get_virtual_function(game_event_manager, 'FireEvent'))
def _pre_game_event(args):
    """Call pre-event functions if the event is registered."""
    # Crashfix for CS:GO:
    # https://github.com/Source-Python-Dev-Team/Source.Python/issues/230
    game_event_ptr = args[1]
    if not game_event_ptr:
        return False

    # Get the GameEvent object
    game_event = make_object(GameEvent, game_event_ptr)

    # Get the name of the event
    event_name = game_event.name

    # If the current event is not in the dictionary, return
Exemple #24
0
        everyone.

        If you want to check if the player is muted only for specific players,
        pass a tuple that contains the player indexes that should be checked.
        """
        return all(map(
            lambda receiver: sender in self[receiver],
            self._get_receivers(receivers)))

mute_manager = _MuteManager(set)


# =============================================================================
# >> CALLBACKS
# =============================================================================
@PreHook(memory.get_virtual_function(voice_server, 'SetClientListening'))
def _pre_set_client_listening(args):
    """Called before IVoiceServer::SetClientListening is called."""
    receiver = args[1]
    sender = args[2]

    # Check if the sender is muted for this receiver
    if mute_manager.is_muted(sender, [receiver]):
        args[3] = False


@ClientDisconnect
def _on_client_disconnect(index):
    """Called when a player left the server."""
    # Unmute the player, so the next player who gets this index won't be muted
    mute_manager.unmute_player(index)

class TempEntityPostHook(TempEntityPreHook):
    """Decorator used to create temp entity post hooks that auto unload."""

    def __init__(self, temp_entity_name):
        """Initialize the hook object.

        :param str temp_entity_name:
            The name of the temp entity to hook.
        """
        from warnings import warn
        warn(
            'TempEntityPostHook has been deprecated and will be entirely '
            'unsupported in a future update. Use TempEntityPreHook instead '
            'or register your own post hook on '
            'CEngineServer::PlaybackTempEntity/CBaseTempEntity::Create.')

        super().__init__(temp_entity_name)


# =============================================================================
# >> HOOKS
# =============================================================================
@PreHook(get_virtual_function(engine_server, 'PlaybackTempEntity'))
def pre_playback_temp_entity(stack_data):
    """Handle pre hooks."""
    temp_entity = TempEntity(stack_data[3])
    return temp_entity.template.handle_hook(temp_entity,
        make_object(RecipientFilter, stack_data[1]))