//--------------------------------------------------------------------------------- // Returns the path to the ../source-python/addon/ directory. //--------------------------------------------------------------------------------- const char *GetSourcePythonDir() { static char szGameDir[MAX_PATH_LENGTH]; engine->GetGameDir(szGameDir, MAX_PATH_LENGTH); GenerateSymlink(szGameDir); static char szAddonDir[MAX_PATH_LENGTH]; V_snprintf(szAddonDir, MAX_PATH_LENGTH, "%s%s", szGameDir, "/addons/source-python"); return szAddonDir; }
//--------------------------------------------------------------------------------- // This function will load libraries and return true if they load successfully. // //--------------------------------------------------------------------------------- void* SPLoadLibrary( IVEngineServer* engine, const char* libraryPath ) { DevMsg(1, MSG_PREFIX "Loading library: %s\n", libraryPath); char szFullPath[MAX_PATH_LENGTH]; char szGamePath[MAX_PATH_LENGTH]; char szError[MAX_PATH_LENGTH]; V_strncpy(szError, "[SP-LOADER] - No error found\n", MAX_PATH_LENGTH); engine->GetGameDir(szGamePath, MAX_PATH_LENGTH); GenerateSymlink(szGamePath); V_snprintf(szFullPath, sizeof(szFullPath), "%s/addons/source-python/%s", szGamePath, libraryPath); // Fix up the slahes. V_FixSlashes(szFullPath); #if defined(_WIN32) void* hModule = (void *)LoadLibrary(szFullPath); if (!hModule) { // I hate windows programming... DWORD nErrorCode = GetLastError(); LPVOID lpMsgBuf; DWORD nBufferLength = FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, nErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL ); if(nBufferLength == 0) { V_snprintf(szError, sizeof(szError), "[SP-LOADER] Could not obtain a valid translation for error. (Code: %d)\n", nErrorCode); } else { char szResult[MAX_ERROR_LENGTH]; memset(szResult, '\0', MAX_ERROR_LENGTH); // Too lazy to bring across any windows functions, cast myself from wide to narrow for (unsigned int i=0; i < nBufferLength; ++i) { szResult[i] = static_cast<char>(static_cast<LPCSTR>(lpMsgBuf)[i]); } V_snprintf(szError, sizeof(szError), "[SP-LOADER] (Code: %d) %s", nErrorCode, szResult/*.c_str()*/); LocalFree(lpMsgBuf); } } #else void* hModule = (void *)dlopen(szFullPath, RTLD_NOW | RTLD_GLOBAL); if (!hModule) { V_snprintf(szError, sizeof(szError), "[SP-LOADER] Error Reported: %s\n", dlerror()); } #endif if( !hModule ) { Warning("=========================================================================\n"); Warning("[SP-LOADER] Could not load library: %s\n", libraryPath); Warning(szError); Warning("=========================================================================\n"); return hModule; } return hModule; }
//--------------------------------------------------------------------------------- // Purpose: called when the plugin is loaded, load the interface we need from the engine //--------------------------------------------------------------------------------- bool CSourcePython::Load( CreateInterfaceFn interfaceFactory, CreateInterfaceFn gameServerFactory ) { Msg(MSG_PREFIX "Loading...\n"); IVEngineServer* engine = (IVEngineServer*)interfaceFactory(INTERFACEVERSION_VENGINESERVER, NULL); // Was the IVEngineServer interface retrieved properly? if (!engine) { Msg(MSG_PREFIX "Unable to retrieve IVEngineServer interface.\n"); return false; } // ------------------------------------------------------------------ // Build path to python engines directory. // ------------------------------------------------------------------ char szGameDir[MAX_PATH_LENGTH]; // ------------------------------------------------------------------ // Get the game directory. // ------------------------------------------------------------------ DevMsg(1, MSG_PREFIX "Retrieving game directory...\n"); engine->GetGameDir(szGameDir, MAX_PATH_LENGTH); DevMsg(1, MSG_PREFIX "Game directory: %s\n", szGameDir); GenerateSymlink(szGameDir); // ------------------------------------------------------------------ // Load windows dependencies. // ------------------------------------------------------------------ #if defined(_WIN32) if( SPLoadLibrary(engine, VCRUNTIME_LIB) == NULL ) { return false; } #endif // ------------------------------------------------------------------ // Load python. // ------------------------------------------------------------------ if( SPLoadLibrary(engine, PYLIB_NAME) == NULL ) { return false; } // ------------------------------------------------------------------ // Load the Source.Python core. // ------------------------------------------------------------------ m_pCore = SPLoadLibrary(engine, CORE_NAME); if (!m_pCore) { return false; } // Sys_LoadModule and CDllDemandLoader seem to be broken in CS:GO #ifdef _WIN32 CreateInterfaceFn pFunc = (CreateInterfaceFn) GetProcAddress((HMODULE) m_pCore, CREATEINTERFACE_PROCNAME); #elif __linux__ CreateInterfaceFn pFunc = (CreateInterfaceFn) dlsym(m_pCore, CREATEINTERFACE_PROCNAME); #else #error Unsupported platform. #endif if (!pFunc) { Msg(MSG_PREFIX "Failed to retrieve %s.\n", CREATEINTERFACE_PROCNAME); return false; } m_pCorePlugin = static_cast<IServerPluginCallbacks*>(pFunc(INTERFACEVERSION_ISERVERPLUGINCALLBACKS, NULL)); if( !m_pCorePlugin ) { Warning("=========================================================================\n"); Warning("[SP-LOADER] Could not retrieve the server plugin interface from the core!\n"); Warning("=========================================================================\n"); return false; } // Pass it on. return m_pCorePlugin->Load(interfaceFactory, gameServerFactory); }