//-----------------------------------------------------------------------------
// Calls all callables for the command when it is called on the server.
//-----------------------------------------------------------------------------
void CServerCommandManager::Dispatch( const CCommand& command )
{
	// Loop through all registered callbacks for the command
	// (use equals also to know when to call the old callback)
	for(int i = 0; i <= m_vecCallables.Count(); i++)
	{

		// Is the current iteration for a registered callback?
		if( i < m_vecCallables.Count() )
		{
			
			BEGIN_BOOST_PY()

				// Get the PyObject instance of the callable
				PyObject* pCallable = m_vecCallables[i].ptr();

				// Call the callable and store its return value
				object returnValue = CALL_PY_FUNC(pCallable, boost::ref(command));

				// Does the callable wish to block the command?
				if( !returnValue.is_none() && extract<int>(returnValue) == (int) BLOCK)
				{
					// Block the command
					break;
				}

			END_BOOST_PY_NORET()
		}

		// Was the command previously registered?
		else if(m_pOldCommand)
//-----------------------------------------------------------------------------
// Calls all callables for the command when it is called on the client.
//-----------------------------------------------------------------------------
CommandReturn CClientCommandManager::Dispatch( const CCommand& command, int iIndex )
{
	// Loop through all callables registered for the CClientCommandManager instance
	for(int i = 0; i < m_vecCallables.Count(); i++)
	{
		BEGIN_BOOST_PY()

			// Get the PyObject instance of the callable
			PyObject* pCallable = m_vecCallables[i].ptr();

			// Call the callable and store its return value
			object returnValue = CALL_PY_FUNC(pCallable, boost::ref(command), iIndex);

			// Does the callable wish to block the command?
			if( !returnValue.is_none() && extract<int>(returnValue) == (int) BLOCK)
			{
				// Block the command
				return BLOCK;
			}

		END_BOOST_PY_NORET()
	}

	return CONTINUE;
}
//-----------------------------------------------------------------------------
// Notifies all registered callbacks.
//-----------------------------------------------------------------------------
void CListenerManager::Notify(tuple args, dict kwargs)
{
	static object callback_caller = eval("lambda func, args, kwargs: func(*args, **kwargs)");
	for(int i = 0; i < m_vecCallables.Count(); i++)
	{
		BEGIN_BOOST_PY()
			callback_caller(m_vecCallables[i], args, kwargs);
		END_BOOST_PY_NORET()
	}
}
//-----------------------------------------------------------------------------
// Calls all registered tick listeners.
//-----------------------------------------------------------------------------
void CTickListenerManager::call_tick_listeners()
{
	for(int i = 0; i < m_vecCallables.Count(); i++)
	{
		BEGIN_BOOST_PY()

			// Get the PyObject instance of the callable
			PyObject* pCallable = m_vecCallables[i].ptr();

			// Call the callable
			CALL_PY_FUNC(pCallable);

		END_BOOST_PY_NORET()
	}
}
//-----------------------------------------------------------------------------
// Dispatches a client command.
//-----------------------------------------------------------------------------
PLUGIN_RESULT DispatchClientCommand(edict_t* pEntity, const CCommand &command)
{
	unsigned int iIndex;
	if (!IndexFromEdict(pEntity, iIndex))
		return PLUGIN_CONTINUE;

	// Loop through all registered Client Command Filters
	for(int i = 0; i < s_ClientCommandFilters.m_vecCallables.Count(); i++)
	{
		BEGIN_BOOST_PY()

			// Get the PyObject instance of the callable
			PyObject* pCallable = s_ClientCommandFilters.m_vecCallables[i].ptr();

			// Call the callable and store its return value
			object returnValue = CALL_PY_FUNC(pCallable, boost::ref(command), iIndex);

			// Does the Client Command Filter want to block the command?
			if( !returnValue.is_none() && extract<int>(returnValue) == (int)BLOCK)
			{
				// Block the command
				return PLUGIN_STOP;
			}

		END_BOOST_PY_NORET()
	}

	// Get the command's name
	const char* szCommand = command.Arg(0);

	// Find if the command exists in the mapping
	ClientCommandMap::iterator commandMapIter = g_ClientCommandMap.find(szCommand);
	if( commandMapIter != g_ClientCommandMap.end() )
	{
		// If the command exists, get the CClientCommandManager instance and call its Dispatch method
		CClientCommandManager* pCClientCommandManager = commandMapIter->second;

		// Does the command need to be blocked?
		if( !pCClientCommandManager->Dispatch(command, iIndex))
		{
			// Block the command
			return PLUGIN_STOP;
		}
	}

	return PLUGIN_CONTINUE;
}
	virtual void Log( const LoggingContext_t *pContext, const tchar *pMessage )
	{
		extern CListenerManager* GetOnServerOutputListenerManager();
		bool block = false;

		for(int i = 0; i < GetOnServerOutputListenerManager()->m_vecCallables.Count(); i++)
		{
			BEGIN_BOOST_PY() 
				object return_value = CALL_PY_FUNC(
					GetOnServerOutputListenerManager()->m_vecCallables[i].ptr(),
					(MessageSeverity) pContext->m_Severity, 
					pMessage);

			if (!return_value.is_none() && extract<OutputReturn>(return_value) == OUTPUT_BLOCK)
					block = true;

			END_BOOST_PY_NORET()
		}

		if (!block)
		{
			// Restore the old logging state before SP has been loaded
			LoggingSystem_PopLoggingState(false);

			// Resend the log message. Our listener won't get called anymore
			LoggingSystem_LogDirect(
					pContext->m_ChannelID,
					pContext->m_Severity,
					pContext->m_Color,
					pMessage);

			// Create a new logging state with only our listener being active
#if defined(ENGINE_LEFT4DEAD2)
			LoggingSystem_PushLoggingState(false);
#else
			LoggingSystem_PushLoggingState(false, true);
#endif
			LoggingSystem_RegisterLoggingListener(this);

		}
	}
SpewRetval_t SP_SpewOutput( SpewType_t spewType, const tchar *pMsg )
{
	extern CListenerManager* GetOnServerOutputListenerManager();
	bool block = false;

	for(int i = 0; i < GetOnServerOutputListenerManager()->m_vecCallables.Count(); i++)
	{
		BEGIN_BOOST_PY() 
			object return_value = CALL_PY_FUNC(
				GetOnServerOutputListenerManager()->m_vecCallables[i].ptr(),
				(MessageSeverity) spewType, 
				pMsg);

		if (!return_value.is_none() && extract<OutputReturn>(return_value) == OUTPUT_BLOCK)
				block = true;

		END_BOOST_PY_NORET()
	}

	if (!block && g_SourcePythonPlugin.m_pOldSpewOutputFunc)
		return g_SourcePythonPlugin.m_pOldSpewOutputFunc(spewType, pMsg);

	return SPEW_CONTINUE;
}
Exemple #8
0
//---------------------------------------------------------------------------------
// Initializes python.
//---------------------------------------------------------------------------------
bool CPythonManager::Initialize( void )
{
	// Construct a path to the python engine directory.
	char szPythonHome[MAX_GAME_PATH];
	V_snprintf(szPythonHome, MAX_GAME_PATH, "%s/Python3", g_GamePaths.GetSPDir());
	V_FixSlashes(szPythonHome);
	DevMsg(1, "[SP] Python home path set to %s\n", szPythonHome);

	// Convert to wide char for python.
	wchar_t wszPythonHome[1024];
	V_strtowcs(szPythonHome, -1, wszPythonHome, 1024);

	// Set that as the python home directory.
 	Py_SetPythonHome(wszPythonHome);
 	Py_SetProgramName(wszPythonHome);
	Py_SetPath(wszPythonHome);

	// Initialize python and its namespaces.
	Py_Initialize();

	// Print some information
	DevMsg(1, "Python version %s initialized!\n", Py_GetVersion());

	// Make sure sys is imported.
	PyRun_SimpleString("import sys");

	// Add the Python API path.
	AddToSysPath("/packages/source-python");

	// Add operating system specific paths.
#if defined(WIN32)
	AddToSysPath("/Python3/plat-win");
#else
	AddToSysPath("/Python3/plat-linux");

	// We've got a bunch of linux shared objects here we need to load.
	AddToSysPath("/Python3/lib-dynload");
#endif

	// Site packages for any extra packages...
	AddToSysPath("/packages/site-packages");

	// Add the custom packages path.
	AddToSysPath("/packages/custom");

	// And of course, the plugins directory for script imports.
	AddToSysPath("/plugins");

	// Initialize all converters
	InitConverters();

	// Initialize all submodules
	modulsp_init();

	// Import the main module file.
	DevMsg(1, "[SP] Importing main module..\n");
	BEGIN_BOOST_PY()

		python::import("__init__");

	END_BOOST_PY_NORET(); // Noret because we have more stuff to do after this import.

	DevMsg(0, "[Source.Python] Loaded successfully.\n");

	return true;
}
//-----------------------------------------------------------------------------
// Dispatches the say and say_team commands.
//-----------------------------------------------------------------------------
void SayConCommand::Dispatch( const CCommand& command )
{
	// This is the case if just "say" or "say_team" was entered into the server
	if (command.ArgC() == 1)
		return;

	// Get the index of the player that used the command
	int iIndex = GetCommandIndex();
	
	// Get the IPlayerInfo instance of the player
	IPlayerInfo* pPlayerInfo = PlayerInfoFromIndex(iIndex);
	
	// Get whether the command was say or say_team
	bool bTeamOnly = strcmp(command.Arg(0), "say_team") == 0;
	
	// Loop through all registered Say Filter callbacks
	for(int i = 0; i < s_SayFilters.m_vecCallables.Count(); i++)
	{
		BEGIN_BOOST_PY()

			// Get the PyObject instance of the callable
			PyObject* pCallable = s_SayFilters.m_vecCallables[i].ptr();

			// Call the callable and store its return value
			object returnValue = CALL_PY_FUNC(pCallable, ptr(pPlayerInfo), bTeamOnly, boost::ref(command));

			// Does the current Say Filter wish to block the command?
			if( !returnValue.is_none() && extract<int>(returnValue) == (int) BLOCK)
			{
				// Block the command
				return;
			}

		END_BOOST_PY_NORET()
	}

	// Get the name of the command used
	std::string szCommandString (command.Arg(1));

	// Copy the string to get a char instance
	char * szCopyCommandString = new char [szCommandString.length() + 1];
	std::strcpy(szCopyCommandString, szCommandString.c_str());

	// Split the command using <space> as the delimiter
	// This should be the actual Say Command
	char * szCommand = std::strtok(szCopyCommandString, " ");

	// Find if the command is registered
	SayCommandMap::iterator commandMapIter = g_SayCommandMap.find(szCommand);
	if( commandMapIter != g_SayCommandMap.end() )
	{
		// Get the CSayCommandManager instance for the command
		CSayCommandManager* pCSayCommandManager = commandMapIter->second;
		
		// Call the command and see it wants to block the command
		if( pCSayCommandManager->Dispatch(pPlayerInfo, bTeamOnly, command)  == BLOCK)
		{
			// Block the command
			return;
		}
	}
	
	// Was the command previously registered?
	if( m_pOldCommand )
	{
		// Call the old command callback
		m_pOldCommand->Dispatch(command);
	}
}