size_t SourceModBase::BuildPath(PathType type, char *buffer, size_t maxlength, const char *format, ...) { char _buffer[PLATFORM_MAX_PATH]; va_list ap; va_start(ap, format); vsnprintf(_buffer, PLATFORM_MAX_PATH, format, ap); va_end(ap); /* If we get a "file://" notation, strip off the file:// part so we're left * with an absolute path. Note that the absolute path gets returned, so * usage with relative paths here is completely invalid. */ if (type != Path_SM_Rel && strncmp(_buffer, "file://", 7) == 0) { return g_LibSys.PathFormat(buffer, maxlength, "%s", &_buffer[7]); } const char *base = NULL; if (type == Path_Game) { base = GetGamePath(); } else if (type == Path_SM) { base = GetSourceModPath(); } else if (type == Path_SM_Rel) { base = m_SMRelDir; } if (base) { return g_LibSys.PathFormat(buffer, maxlength, "%s/%s", base, _buffer); } else { return g_LibSys.PathFormat(buffer, maxlength, "%s", _buffer); } }
bool SourceModBase::InitializeSourceMod(char *error, size_t maxlength, bool late) { const char *gamepath = g_SMAPI->GetBaseDir(); /* Store full path to game */ g_BaseDir.assign(gamepath); /* Store name of game directory by itself */ size_t len = strlen(gamepath); for (size_t i = len - 1; i < len; i--) { if (gamepath[i] == PLATFORM_SEP_CHAR) { strncopy(m_ModDir, &gamepath[++i], sizeof(m_ModDir)); break; } } const char *basepath = icvar->GetCommandLineValue("sm_basepath"); /* Set a custom base path if there is one. */ if (basepath != NULL && basepath[0] != '\0') { m_GotBasePath = true; } /* Otherwise, use a default and keep the m_GotBasePath unlocked. */ else { basepath = sm_basepath.GetDefault(); } g_LibSys.PathFormat(m_SMBaseDir, sizeof(m_SMBaseDir), "%s/%s", g_BaseDir.c_str(), basepath); g_LibSys.PathFormat(m_SMRelDir, sizeof(m_SMRelDir), "%s", basepath); if (!StartLogicBridge(error, maxlength)) { return false; } /* There will always be a path by this point, since it was force-set above. */ m_GotBasePath = true; /* Attempt to load the JIT! */ char file[PLATFORM_MAX_PATH]; char myerror[255]; g_SMAPI->PathFormat(file, sizeof(file), "%s/bin/sourcepawn.jit.x86.%s", GetSourceModPath(), PLATFORM_LIB_EXT ); g_pJIT = g_LibSys.OpenLibrary(file, myerror, sizeof(myerror)); if (!g_pJIT) { if (error && maxlength) { UTIL_Format(error, maxlength, "%s (failed to load bin/sourcepawn.jit.x86.%s)", myerror, PLATFORM_LIB_EXT); } return false; } GetSourcePawnFactoryFn factoryFn = (GetSourcePawnFactoryFn)g_pJIT->GetSymbolAddress("GetSourcePawnFactory"); if (!factoryFn) { if (error && maxlength) snprintf(error, maxlength, "SourcePawn library is out of date"); ShutdownJIT(); return false; } ISourcePawnFactory *factory = factoryFn(SOURCEPAWN_API_VERSION); if (!factory) { if (error && maxlength) snprintf(error, maxlength, "SourcePawn library is out of date"); ShutdownJIT(); return false; } g_pPawnEnv = factory->NewEnvironment(); if (!g_pPawnEnv) { if (error && maxlength) snprintf(error, maxlength, "Could not create a SourcePawn environment!"); ShutdownJIT(); return false; } g_pSourcePawn = g_pPawnEnv->APIv1(); g_pSourcePawn2 = g_pPawnEnv->APIv2(); g_pSourcePawn2->SetDebugListener(logicore.debugger); if (sm_disable_jit) g_pSourcePawn2->SetJitEnabled(!sm_disable_jit); sSourceModInitialized = true; /* Hook this now so we can detect startup without calling StartSourceMod() */ SH_ADD_HOOK(IServerGameDLL, LevelInit, gamedll, SH_MEMBER(this, &SourceModBase::LevelInit), false); /* Only load if we're not late */ if (!late) { StartSourceMod(false); } return true; }
bool SourceModBase::InitializeSourceMod(char *error, size_t maxlength, bool late) { const char *gamepath = g_SMAPI->GetBaseDir(); /* Store full path to game */ g_BaseDir.assign(gamepath); /* Store name of game directory by itself */ size_t len = strlen(gamepath); for (size_t i = len - 1; i < len; i--) { if (gamepath[i] == PLATFORM_SEP_CHAR) { strncopy(m_ModDir, &gamepath[++i], sizeof(m_ModDir)); break; } } const char *basepath = icvar->GetCommandLineValue("sm_basepath"); /* Set a custom base path if there is one. */ if (basepath != NULL && basepath[0] != '\0') { m_GotBasePath = true; } /* Otherwise, use a default and keep the m_GotBasePath unlocked. */ else { basepath = sm_basepath.GetDefault(); } g_LibSys.PathFormat(m_SMBaseDir, sizeof(m_SMBaseDir), "%s/%s", g_BaseDir.c_str(), basepath); g_LibSys.PathFormat(m_SMRelDir, sizeof(m_SMRelDir), "%s", basepath); if (!StartLogicBridge(error, maxlength)) { return false; } /* Initialize CoreConfig to get the SourceMod base path properly - this parses core.cfg */ g_CoreConfig.Initialize(); /* There will always be a path by this point, since it was force-set above. */ m_GotBasePath = true; /* Attempt to load the JIT! */ char file[PLATFORM_MAX_PATH]; char myerror[255]; g_SMAPI->PathFormat(file, sizeof(file), "%s/bin/sourcepawn.jit.x86.%s", GetSourceModPath(), PLATFORM_LIB_EXT ); g_pJIT = g_LibSys.OpenLibrary(file, myerror, sizeof(myerror)); if (!g_pJIT) { if (error && maxlength) { UTIL_Format(error, maxlength, "%s (failed to load bin/sourcepawn.jit.x86.%s)", myerror, PLATFORM_LIB_EXT); } return false; } GET_SP_V1 getv1 = (GET_SP_V1)g_pJIT->GetSymbolAddress("GetSourcePawnEngine1"); GET_SP_V2 getv2 = (GET_SP_V2)g_pJIT->GetSymbolAddress("GetSourcePawnEngine2"); if (getv1 == NULL) { if (error && maxlength) { snprintf(error, maxlength, "JIT is too old; upgrade SourceMod"); } ShutdownJIT(); return false; } else if (getv2 == NULL) { if (error && maxlength) { snprintf(error, maxlength, "JIT is too old; upgrade SourceMod"); } ShutdownJIT(); return false; } g_pSourcePawn = getv1(); g_pSourcePawn2 = getv2(); if (g_pSourcePawn2->GetAPIVersion() < 3) { g_pSourcePawn2 = NULL; if (error && maxlength) { snprintf(error, maxlength, "JIT version is out of date"); } return false; } if (!g_pSourcePawn2->Initialize()) { g_pSourcePawn2 = NULL; if (error && maxlength) { snprintf(error, maxlength, "JIT could not be initialized"); } return false; } g_pSourcePawn2->SetDebugListener(logicore.debugger); if (sm_disable_jit) g_pSourcePawn2->SetJitEnabled(!sm_disable_jit); sSourceModInitialized = true; /* Hook this now so we can detect startup without calling StartSourceMod() */ SH_ADD_HOOK(IServerGameDLL, LevelInit, gamedll, SH_MEMBER(this, &SourceModBase::LevelInit), false); /* Only load if we're not late */ if (!late) { StartSourceMod(false); } return true; }