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)
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
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()
# ============================================================================= @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
# 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
""" 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
# 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
# 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:
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)
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)
@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:]
""" 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
@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'
: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
# 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
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]))