dvander@370: /** dvander@2726: * vim: set ts=4 sw=4 : ds@1330: * ============================================================================= dvander@1231: * SourceMod ds@3104: * Copyright (C) 2004-2010 AlliedModders LLC. All rights reserved. ds@1330: * ============================================================================= dvander@370: * ds@1330: * This program is free software; you can redistribute it and/or modify it under ds@1330: * the terms of the GNU General Public License, version 3.0, as published by the ds@1330: * Free Software Foundation. dvander@1231: * ds@1330: * This program is distributed in the hope that it will be useful, but WITHOUT ds@1330: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS ds@1330: * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ds@1330: * details. dvander@1231: * ds@1330: * You should have received a copy of the GNU General Public License along with ds@1330: * this program. If not, see . dvander@1231: * ds@1330: * As a special exception, AlliedModders LLC gives you permission to link the ds@1330: * code of this program (as well as its derivative works) to "Half-Life 2," the ds@1330: * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software ds@1330: * by the Valve Corporation. You must obey the GNU General Public License in ds@1330: * all respects for all other code used. Additionally, AlliedModders LLC grants ds@1330: * this exception to all derivative works. AlliedModders LLC defines further ds@1330: * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), ds@1330: * or . dvander@370: * dvander@370: * Version: $Id$ dvander@370: */ dvander@370: dvander@160: #include dvander@160: #include "sourcemod.h" dvander@160: #include "sourcemm_api.h" dvander@2411: #include "LibrarySys.h" dvander@160: #include ds@661: #include "CoreConfig.h" dvander@592: #include "Logger.h" dvander@340: #include "AdminCache.h" dvander@347: #include "sm_stringutil.h" dvander@591: #include "PlayerManager.h" dvander@531: #include "ForwardSys.h" faluco@593: #include "TimerSys.h" dvander@3010: #include dvander@2562: #include "frame_hooks.h" dvander@2726: #include "logic_bridge.h" dvander@160: dvander@209: SH_DECL_HOOK6(IServerGameDLL, LevelInit, SH_NOATTRIB, false, bool, const char *, const char *, const char *, const char *, bool, bool); faluco@333: SH_DECL_HOOK0_void(IServerGameDLL, LevelShutdown, SH_NOATTRIB, false); dvander@448: SH_DECL_HOOK1_void(IServerGameDLL, GameFrame, SH_NOATTRIB, false, bool); dvander@978: SH_DECL_HOOK1_void(IVEngineServer, ServerCommand, SH_NOATTRIB, false, const char *); dvander@209: dvander@160: SourceModBase g_SourceMod; dvander@160: dvander@160: ILibrary *g_pJIT = NULL; dvander@160: SourceHook::String g_BaseDir; dvander@2193: ISourcePawnEngine *g_pSourcePawn = NULL; dvander@2193: ISourcePawnEngine2 *g_pSourcePawn2 = NULL; dvander@252: IdentityToken_t *g_pCoreIdent = NULL; dvander@718: IForward *g_pOnMapEnd = NULL; dvander@3010: IGameConfig *g_pGameConf = NULL; dvander@688: bool g_Loaded = false; dvander@2474: bool sm_show_debug_spew = false; dvander@160: dvander@2193: typedef ISourcePawnEngine *(*GET_SP_V1)(); dvander@2193: typedef ISourcePawnEngine2 *(*GET_SP_V2)(); dvander@160: typedef void (*NOTIFYSHUTDOWN)(); dvander@160: dvander@2572: #ifdef PLATFORM_WINDOWS dvander@2572: ConVar sm_basepath("sm_basepath", "addons\\sourcemod", 0, "SourceMod base path (set via command line)"); dvander@2572: #elif defined PLATFORM_LINUX || defined PLATFORM_APPLE dvander@2572: ConVar sm_basepath("sm_basepath", "addons/sourcemod", 0, "SourceMod base path (set via command line)"); dvander@2572: #endif dvander@2572: dvander@160: void ShutdownJIT() dvander@160: { dvander@160: NOTIFYSHUTDOWN notify = (NOTIFYSHUTDOWN)g_pJIT->GetSymbolAddress("NotifyShutdown"); dvander@160: if (notify) dvander@160: { dvander@160: notify(); dvander@160: } dvander@160: dvander@2226: if (g_pSourcePawn2 != NULL) dvander@2226: { dvander@2226: g_pSourcePawn2->Shutdown(); dvander@2226: } dvander@2226: dvander@160: g_pJIT->CloseLibrary(); dvander@160: } dvander@160: dvander@209: SourceModBase::SourceModBase() dvander@209: { dvander@209: m_IsMapLoading = false; faluco@333: m_ExecPluginReload = false; ds@661: m_GotBasePath = false; ds@661: } ds@661: dvander@663: ConfigResult SourceModBase::OnSourceModConfigChanged(const char *key, dvander@663: const char *value, dvander@663: ConfigSource source, dvander@663: char *error, dvander@663: size_t maxlength) ds@661: { dvander@665: if (strcasecmp(key, "BasePath") == 0) ds@661: { dvander@663: if (source == ConfigSource_Console) dvander@663: { dvander@663: UTIL_Format(error, maxlength, "Cannot be set at runtime"); dvander@663: return ConfigResult_Reject; dvander@663: } dvander@663: ds@661: if (!m_GotBasePath) ds@661: { ds@661: g_LibSys.PathFormat(m_SMBaseDir, sizeof(m_SMBaseDir), "%s/%s", g_BaseDir.c_str(), value); ds@661: g_LibSys.PathFormat(m_SMRelDir, sizeof(m_SMRelDir), value); ds@661: ds@661: m_GotBasePath = true; dvander@663: } ds@661: dvander@663: return ConfigResult_Accept; ds@661: } dvander@2474: else if (strcasecmp(key, "DebugSpew") == 0) dvander@2474: { dvander@2474: sm_show_debug_spew = (strcasecmp(value, "yes") == 0) ? true : false; dvander@2474: dvander@2474: return ConfigResult_Accept; dvander@2474: } ds@661: dvander@663: return ConfigResult_Ignore; dvander@209: } dvander@209: ds@755: bool SourceModBase::InitializeSourceMod(char *error, size_t maxlength, bool late) dvander@160: { ds@696: const char *gamepath = g_SMAPI->GetBaseDir(); ds@696: ds@696: /* Store full path to game */ ds@696: g_BaseDir.assign(gamepath); ds@696: ds@696: /* Store name of game directory by itself */ ds@696: size_t len = strlen(gamepath); ds@3261: for (size_t i = len - 1; i < len; i--) ds@696: { ds@696: if (gamepath[i] == PLATFORM_SEP_CHAR) ds@696: { ds@696: strncopy(m_ModDir, &gamepath[++i], sizeof(m_ModDir)); ds@696: break; ds@696: } ds@696: } ds@661: dvander@2572: const char *basepath = icvar->GetCommandLineValue("sm_basepath"); dvander@2572: /* Set a custom base path if there is one. */ dvander@2572: if (basepath != NULL && basepath[0] != '\0') dvander@2572: { dvander@2572: m_GotBasePath = true; dvander@2572: } dvander@2572: /* Otherwise, use a default and keep the m_GotBasePath unlocked. */ dvander@2572: else dvander@2572: { dvander@2572: basepath = sm_basepath.GetDefault(); dvander@2572: } dvander@2572: dvander@2572: g_LibSys.PathFormat(m_SMBaseDir, sizeof(m_SMBaseDir), "%s/%s", g_BaseDir.c_str(), basepath); dvander@2572: g_LibSys.PathFormat(m_SMRelDir, sizeof(m_SMRelDir), "%s", basepath); dvander@2572: dvander@2726: if (!StartLogicBridge(error, maxlength)) dvander@2726: { dvander@2726: return false; dvander@2726: } dvander@2726: dvander@2572: /* Initialize CoreConfig to get the SourceMod base path properly - this parses core.cfg */ ds@661: g_CoreConfig.Initialize(); ds@661: dvander@2572: /* There will always be a path by this point, since it was force-set above. */ dvander@2572: m_GotBasePath = true; dvander@160: dvander@160: /* Attempt to load the JIT! */ dvander@160: char file[PLATFORM_MAX_PATH]; dvander@160: char myerror[255]; dvander@209: g_SMAPI->PathFormat(file, sizeof(file), "%s/bin/sourcepawn.jit.x86.%s", dvander@317: GetSourceModPath(), dvander@160: PLATFORM_LIB_EXT dvander@160: ); dvander@160: dvander@160: g_pJIT = g_LibSys.OpenLibrary(file, myerror, sizeof(myerror)); dvander@160: if (!g_pJIT) dvander@160: { ds@755: if (error && maxlength) dvander@160: { dvander@2726: UTIL_Format(error, maxlength, "%s (failed to load bin/sourcepawn.jit.x86.%s)", dvander@160: myerror, dvander@160: PLATFORM_LIB_EXT); dvander@160: } dvander@160: return false; dvander@160: } dvander@160: dvander@2193: GET_SP_V1 getv1 = (GET_SP_V1)g_pJIT->GetSymbolAddress("GetSourcePawnEngine1"); dvander@2193: GET_SP_V2 getv2 = (GET_SP_V2)g_pJIT->GetSymbolAddress("GetSourcePawnEngine2"); ds@1952: dvander@2193: if (getv1 == NULL) dvander@160: { ds@1952: if (error && maxlength) dvander@160: { dvander@2193: snprintf(error, maxlength, "JIT is too old; upgrade SourceMod"); dvander@160: } dvander@2193: ShutdownJIT(); dvander@2193: return false; dvander@2193: } dvander@2193: else if (getv2 == NULL) dvander@2193: { dvander@2193: if (error && maxlength) dvander@1147: { dvander@2193: snprintf(error, maxlength, "JIT is too old; upgrade SourceMod"); dvander@1147: } dvander@2193: ShutdownJIT(); ds@1952: return false; dvander@160: } dvander@160: dvander@2193: g_pSourcePawn = getv1(); dvander@2193: g_pSourcePawn2 = getv2(); ds@1952: dvander@2545: if (g_pSourcePawn2->GetAPIVersion() < 3) dvander@160: { dvander@2226: g_pSourcePawn2 = NULL; ds@755: if (error && maxlength) dvander@160: { dvander@2226: snprintf(error, maxlength, "JIT version is out of date"); dvander@160: } dvander@160: return false; dvander@160: } dvander@160: dvander@2226: if (!g_pSourcePawn2->Initialize()) dvander@160: { dvander@2226: g_pSourcePawn2 = NULL; ds@755: if (error && maxlength) dvander@160: { dvander@2226: snprintf(error, maxlength, "JIT could not be initialized"); dvander@160: } dvander@160: return false; dvander@160: } dvander@160: dvander@3792: g_pSourcePawn2->SetDebugListener(logicore.debugger); dvander@176: dvander@688: /* Hook this now so we can detect startup without calling StartSourceMod() */ kyle@3819: SH_ADD_HOOK(IServerGameDLL, LevelInit, gamedll, SH_MEMBER(this, &SourceModBase::LevelInit), false); dvander@688: dvander@688: /* Only load if we're not late */ dvander@688: if (!late) dvander@688: { dvander@688: StartSourceMod(false); dvander@688: } dvander@176: dvander@160: return true; dvander@160: } dvander@209: dvander@209: void SourceModBase::StartSourceMod(bool late) dvander@209: { kyle@3819: SH_ADD_HOOK(IServerGameDLL, LevelShutdown, gamedll, SH_MEMBER(this, &SourceModBase::LevelShutdown), false); kyle@3819: SH_ADD_HOOK(IServerGameDLL, GameFrame, gamedll, SH_MEMBER(&g_Timers, &TimerSystem::GameFrame), false); dvander@209: dvander@496: enginePatch = SH_GET_CALLCLASS(engine); dvander@532: gamedllPatch = SH_GET_CALLCLASS(gamedll); dvander@496: dvander@2726: InitLogicBridge(); dvander@2726: dvander@214: /* Notify! */ dvander@214: SMGlobalClass *pBase = SMGlobalClass::head; dvander@214: while (pBase) dvander@214: { dvander@315: pBase->OnSourceModStartup(false); dvander@214: pBase = pBase->m_pGlobalClassNext; dvander@214: } dvander@3010: g_pGameConf = logicore.GetCoreGameConfig(); dvander@214: dvander@214: /* Notify! */ dvander@214: pBase = SMGlobalClass::head; dvander@214: while (pBase) dvander@214: { dvander@214: pBase->OnSourceModAllInitialized(); dvander@214: pBase = pBase->m_pGlobalClassNext; dvander@214: } dvander@317: dvander@1915: /* Notify! */ dvander@1915: pBase = SMGlobalClass::head; dvander@1915: while (pBase) dvander@1915: { dvander@1915: pBase->OnSourceModAllInitialized_Post(); dvander@1915: pBase = pBase->m_pGlobalClassNext; dvander@1915: } dvander@1915: dvander@317: /* Add us now... */ dvander@3872: sharesys->AddInterface(NULL, this); dvander@688: dvander@688: /* We're loaded! */ dvander@688: g_Loaded = true; dvander@1581: dvander@1581: /* Initialize VSP stuff */ dvander@1581: if (vsp_interface != NULL) dvander@1581: { dvander@1581: g_SourceMod_Core.OnVSPListening(vsp_interface); dvander@1581: } dvander@2632: skamonkey@3883: if (late) skamonkey@3883: { skamonkey@3883: /* We missed doing anythin gin this if we late-loaded. Sneak it in now. */ skamonkey@3883: AllPluginsLoaded(); skamonkey@3883: } skamonkey@3883: dvander@2632: /* If we want to autoload, do that now */ dvander@2632: const char *disabled = GetCoreConfigValue("DisableAutoUpdate"); dvander@2632: if (disabled == NULL || strcasecmp(disabled, "yes") != 0) dvander@2632: { dvander@3872: extsys->LoadAutoExtension("updater.ext." PLATFORM_LIB_EXT); dvander@2632: } dvander@209: } dvander@209: dvander@916: static bool g_LevelEndBarrier = false; dvander@209: bool SourceModBase::LevelInit(char const *pMapName, char const *pMapEntities, char const *pOldLevel, char const *pLandmarkName, bool loadGame, bool background) dvander@209: { dvander@688: /* If we're not loaded... */ dvander@688: if (!g_Loaded) dvander@688: { dvander@688: /* Do all global initialization now */ dvander@688: StartSourceMod(true); dvander@688: } dvander@688: dvander@209: m_IsMapLoading = true; faluco@333: m_ExecPluginReload = true; dvander@209: dvander@673: /* Notify! */ dvander@673: SMGlobalClass *pBase = SMGlobalClass::head; dvander@673: while (pBase) dvander@673: { dvander@673: pBase->OnSourceModLevelChange(pMapName); dvander@673: pBase = pBase->m_pGlobalClassNext; dvander@673: } dvander@520: dvander@209: DoGlobalPluginLoads(); dvander@209: dvander@209: m_IsMapLoading = false; dvander@209: dvander@673: /* Notify! */ dvander@673: pBase = SMGlobalClass::head; dvander@673: while (pBase) dvander@673: { dvander@673: pBase->OnSourceModPluginsLoaded(); dvander@673: pBase = pBase->m_pGlobalClassNext; dvander@673: } dvander@340: dvander@718: if (!g_pOnMapEnd) dvander@718: { dvander@718: g_pOnMapEnd = g_Forwards.CreateForward("OnMapEnd", ET_Ignore, 0, NULL); dvander@718: } dvander@718: dvander@916: g_LevelEndBarrier = true; dvander@916: dvander@209: RETURN_META_VALUE(MRES_IGNORED, true); dvander@209: } dvander@209: faluco@333: void SourceModBase::LevelShutdown() faluco@333: { dvander@916: if (g_LevelEndBarrier) dvander@916: { dvander@916: SMGlobalClass *next = SMGlobalClass::head; dvander@916: while (next) dvander@916: { dvander@916: next->OnSourceModLevelEnd(); dvander@916: next = next->m_pGlobalClassNext; dvander@916: } dvander@1721: dvander@1721: if (g_pOnMapEnd != NULL) dvander@1721: { dvander@1721: g_pOnMapEnd->Execute(NULL); dvander@1721: } dvander@916: dvander@1721: g_Timers.RemoveMapChangeTimers(); dvander@1721: dvander@1721: g_LevelEndBarrier = false; dvander@718: } dvander@718: dvander@848: g_OnMapStarted = false; dvander@848: faluco@333: if (m_ExecPluginReload) faluco@333: { dvander@3872: scripts->RefreshAll(); faluco@333: m_ExecPluginReload = false; faluco@333: } faluco@333: } faluco@333: faluco@484: bool SourceModBase::IsMapLoading() const dvander@315: { dvander@315: return m_IsMapLoading; dvander@315: } dvander@315: dvander@209: void SourceModBase::DoGlobalPluginLoads() dvander@209: { dvander@209: char config_path[PLATFORM_MAX_PATH]; dvander@209: char plugins_path[PLATFORM_MAX_PATH]; dvander@209: dvander@317: BuildPath(Path_SM, config_path, dvander@209: sizeof(config_path), dvander@317: "configs/plugin_settings.cfg"); dvander@317: BuildPath(Path_SM, plugins_path, dvander@209: sizeof(plugins_path), dvander@317: "plugins"); dvander@209: dvander@397: /* Load any auto extensions */ dvander@3872: extsys->TryAutoload(); dvander@397: dvander@1655: /* Fire the extensions ready message */ dvander@2562: g_SMAPI->MetaFactory(SOURCEMOD_NOTICE_EXTENSIONS, NULL, NULL); dvander@1655: dvander@1380: /* Load any game extension */ dvander@1380: const char *game_ext; dvander@1380: if ((game_ext = g_pGameConf->GetKeyValue("GameExtension")) != NULL) dvander@1380: { dvander@1380: char path[PLATFORM_MAX_PATH]; dvander@1568: UTIL_Format(path, sizeof(path), "%s.ext." PLATFORM_LIB_EXT, game_ext); dvander@3872: extsys->LoadAutoExtension(path); dvander@1380: } dvander@1380: dvander@3872: scripts->LoadAll(config_path, plugins_path); dvander@211: } dvander@211: ds@1411: size_t SourceModBase::BuildPath(PathType type, char *buffer, size_t maxlength, const char *format, ...) dvander@317: { ds@652: char _buffer[PLATFORM_MAX_PATH]; dvander@317: va_list ap; dvander@317: dvander@317: va_start(ap, format); dvander@317: vsnprintf(_buffer, PLATFORM_MAX_PATH, format, ap); dvander@317: va_end(ap); dvander@317: dvander@1729: /* If we get a "file://" notation, strip off the file:// part so we're left dvander@1729: * with an absolute path. Note that the absolute path gets returned, so dvander@1729: * usage with relative paths here is completely invalid. dvander@1729: */ dvander@1729: if (type != Path_SM_Rel && strncmp(_buffer, "file://", 7) == 0) dvander@1729: { dvander@1729: return g_LibSys.PathFormat(buffer, maxlength, "%s", &_buffer[7]); dvander@1729: } dvander@1729: dvander@317: const char *base = NULL; dvander@317: if (type == Path_Game) dvander@317: { ds@729: base = GetGamePath(); dvander@1729: } dvander@1729: else if (type == Path_SM) dvander@1729: { dvander@317: base = GetSourceModPath(); dvander@1729: } dvander@1729: else if (type == Path_SM_Rel) dvander@1729: { dvander@345: base = m_SMRelDir; dvander@317: } dvander@317: dvander@317: if (base) dvander@317: { dvander@317: return g_LibSys.PathFormat(buffer, maxlength, "%s/%s", base, _buffer); dvander@1729: } dvander@1729: else dvander@1729: { dvander@317: return g_LibSys.PathFormat(buffer, maxlength, "%s", _buffer); dvander@317: } dvander@317: } dvander@317: faluco@289: void SourceModBase::CloseSourceMod() faluco@289: { dvander@1018: /* Force a level end */ dvander@1018: LevelShutdown(); dvander@1018: dvander@1018: /* Unload plugins */ dvander@3872: scripts->Shutdown(); dvander@1018: dvander@1018: /* Unload extensions */ dvander@3872: extsys->Shutdown(); dvander@1018: kyle@3819: SH_REMOVE_HOOK(IServerGameDLL, LevelInit, gamedll, SH_MEMBER(this, &SourceModBase::LevelInit), false); faluco@484: dvander@688: if (g_Loaded) dvander@496: { dvander@718: if (g_pOnMapEnd) dvander@718: { dvander@718: g_Forwards.ReleaseForward(g_pOnMapEnd); dvander@718: } dvander@688: dvander@688: /* Notify! */ dvander@688: SMGlobalClass *pBase = SMGlobalClass::head; dvander@688: while (pBase) dvander@688: { dvander@688: pBase->OnSourceModShutdown(); dvander@688: pBase = pBase->m_pGlobalClassNext; dvander@688: } dvander@688: dvander@688: /* Delete all data packs */ dvander@688: CStack::iterator iter; dvander@688: CDataPack *pd; dvander@688: for (iter=m_freepacks.begin(); iter!=m_freepacks.end(); iter++) dvander@688: { dvander@688: pd = (*iter); dvander@688: delete pd; dvander@688: } dvander@688: m_freepacks.popall(); dvander@688: dvander@688: /* Notify! */ dvander@688: pBase = SMGlobalClass::head; dvander@688: while (pBase) dvander@688: { dvander@688: pBase->OnSourceModAllShutdown(); dvander@688: pBase = pBase->m_pGlobalClassNext; dvander@688: } dvander@688: dvander@688: if (enginePatch) dvander@688: { dvander@688: SH_RELEASE_CALLCLASS(enginePatch); dvander@688: enginePatch = NULL; dvander@688: } dvander@688: dvander@688: if (gamedllPatch) dvander@688: { dvander@688: SH_RELEASE_CALLCLASS(gamedllPatch); dvander@688: gamedllPatch = NULL; dvander@688: } dvander@496: kyle@3819: SH_REMOVE_HOOK(IServerGameDLL, LevelShutdown, gamedll, SH_MEMBER(this, &SourceModBase::LevelShutdown), false); kyle@3819: SH_REMOVE_HOOK(IServerGameDLL, GameFrame, gamedll, SH_MEMBER(&g_Timers, &TimerSystem::GameFrame), false); dvander@532: } dvander@532: faluco@289: /* Rest In Peace */ dvander@2726: ShutdownLogicBridge(); faluco@289: ShutdownJIT(); faluco@289: } faluco@289: dvander@317: void SourceModBase::LogMessage(IExtension *pExt, const char *format, ...) dvander@317: { dvander@317: IExtensionInterface *pAPI = pExt->GetAPI(); dvander@317: const char *tag = pAPI->GetExtensionTag(); dvander@317: char buffer[2048]; dvander@317: va_list ap; dvander@317: dvander@317: va_start(ap, format); dvander@317: vsnprintf(buffer, sizeof(buffer), format, ap); dvander@317: va_end(ap); dvander@317: dvander@317: if (tag) dvander@317: { dvander@317: g_Logger.LogMessage("[%s] %s", tag, buffer); dvander@317: } else { dvander@317: g_Logger.LogMessage("%s", buffer); dvander@317: } dvander@317: } dvander@317: dvander@317: void SourceModBase::LogError(IExtension *pExt, const char *format, ...) dvander@317: { dvander@317: IExtensionInterface *pAPI = pExt->GetAPI(); dvander@317: const char *tag = pAPI->GetExtensionTag(); dvander@317: char buffer[2048]; dvander@317: va_list ap; dvander@317: dvander@317: va_start(ap, format); dvander@317: vsnprintf(buffer, sizeof(buffer), format, ap); dvander@317: va_end(ap); dvander@317: dvander@317: if (tag) dvander@317: { dvander@317: g_Logger.LogError("[%s] %s", tag, buffer); dvander@317: } else { dvander@317: g_Logger.LogError("%s", buffer); dvander@317: } dvander@317: } dvander@317: dvander@347: size_t SourceModBase::FormatString(char *buffer, size_t maxlength, IPluginContext *pContext, const cell_t *params, unsigned int param) dvander@347: { dvander@347: char *fmt; dvander@347: dvander@347: pContext->LocalToString(params[param], &fmt); dvander@347: dvander@347: int lparam = ++param; dvander@347: dvander@347: return atcprintf(buffer, maxlength, fmt, pContext, params, &lparam); dvander@347: } dvander@347: faluco@484: const char *SourceModBase::GetSourceModPath() const dvander@209: { dvander@209: return m_SMBaseDir; dvander@209: } dvander@211: ds@729: const char *SourceModBase::GetGamePath() const dvander@255: { dvander@255: return g_BaseDir.c_str(); dvander@255: } dvander@255: dvander@1690: unsigned int SourceModBase::SetGlobalTarget(unsigned int index) faluco@422: { dvander@1690: unsigned int old = m_target; faluco@422: m_target = index; dvander@1690: return old; faluco@422: } faluco@422: faluco@422: unsigned int SourceModBase::GetGlobalTarget() const faluco@422: { faluco@422: return m_target; faluco@422: } faluco@422: faluco@484: IDataPack *SourceModBase::CreateDataPack() faluco@484: { faluco@484: CDataPack *pack; faluco@484: if (m_freepacks.empty()) faluco@484: { faluco@484: pack = new CDataPack; faluco@484: } else { faluco@484: pack = m_freepacks.front(); faluco@484: m_freepacks.pop(); faluco@484: pack->Initialize(); faluco@484: } faluco@484: return pack; faluco@484: } faluco@484: faluco@484: void SourceModBase::FreeDataPack(IDataPack *pack) faluco@484: { faluco@484: m_freepacks.push(static_cast(pack)); faluco@484: } faluco@484: faluco@484: Handle_t SourceModBase::GetDataPackHandleType(bool readonly) faluco@484: { faluco@484: //:TODO: faluco@484: return 0; faluco@484: } faluco@484: ds@729: const char *SourceModBase::GetGameFolderName() const ds@696: { ds@696: return m_ModDir; ds@696: } ds@696: faluco@733: ISourcePawnEngine *SourceModBase::GetScriptingEngine() faluco@733: { faluco@733: return g_pSourcePawn; faluco@733: } faluco@733: faluco@733: IVirtualMachine *SourceModBase::GetScriptingVM() faluco@733: { dvander@2193: return NULL; faluco@733: } faluco@733: dvander@893: void SourceModBase::AllPluginsLoaded() dvander@893: { skamonkey@3883: if (!g_Loaded) skamonkey@3883: { skamonkey@3883: return; skamonkey@3883: } skamonkey@3883: dvander@893: SMGlobalClass *base = SMGlobalClass::head; dvander@893: while (base) dvander@893: { dvander@893: base->OnSourceModGameInitialized(); dvander@893: base = base->m_pGlobalClassNext; dvander@893: } dvander@893: } dvander@893: dvander@1371: time_t SourceModBase::GetAdjustedTime() dvander@1371: { pred@1921: return ::GetAdjustedTime(); dvander@1371: } dvander@1371: dvander@1904: void SourceModBase::AddGameFrameHook(GAME_FRAME_HOOK hook) dvander@1904: { dvander@1904: m_frame_hooks.push_back(hook); dvander@1904: } dvander@1904: dvander@1904: void SourceModBase::RemoveGameFrameHook(GAME_FRAME_HOOK hook) dvander@1904: { dvander@1904: for (size_t i = 0; i < m_frame_hooks.size(); i++) dvander@1904: { dvander@1904: if (m_frame_hooks[i] == hook) dvander@1904: { dvander@1904: m_frame_hooks.erase(m_frame_hooks.iterAt(i)); dvander@1904: return; dvander@1904: } dvander@1904: } dvander@1904: } dvander@1904: dvander@1904: void SourceModBase::ProcessGameFrameHooks(bool simulating) dvander@1904: { dvander@1904: if (m_frame_hooks.size() == 0) dvander@1904: { dvander@1904: return; dvander@1904: } dvander@1904: dvander@1904: for (size_t i = 0; i < m_frame_hooks.size(); i++) dvander@1904: { dvander@1904: m_frame_hooks[i](simulating); dvander@1904: } dvander@1904: } dvander@1904: dvander@2555: size_t SourceModBase::Format(char *buffer, size_t maxlength, const char *fmt, ...) dvander@2555: { dvander@2555: size_t len; dvander@2555: va_list ap; dvander@2555: dvander@2555: va_start(ap, fmt); dvander@2555: len = FormatArgs(buffer, maxlength, fmt, ap); dvander@2555: va_end(ap); dvander@2555: dvander@2555: return len; dvander@2555: } dvander@2555: dvander@2555: size_t SourceModBase::FormatArgs(char *buffer, dvander@2555: size_t maxlength, dvander@2555: const char *fmt, dvander@2555: va_list ap) dvander@2555: { dvander@2555: return UTIL_FormatArgs(buffer, maxlength, fmt, ap); dvander@2555: } dvander@2555: dvander@2562: void SourceModBase::AddFrameAction(FRAMEACTION fn, void *data) dvander@2562: { dvander@2562: ::AddFrameAction(FrameAction(fn, data)); dvander@2562: } dvander@2562: dvander@2574: const char *SourceModBase::GetCoreConfigValue(const char *key) dvander@2574: { dvander@2574: return g_CoreConfig.GetCoreConfigValue(key); dvander@2574: } dvander@2574: dvander@2628: int SourceModBase::GetPluginId() dvander@2628: { dvander@2628: return g_PLID; dvander@2628: } dvander@2628: ds@3104: int SourceModBase::GetShApiVersion() ds@3104: { ds@3104: int api, impl; ds@3104: g_SMAPI->GetShVersions(api, impl); ds@3104: ds@3104: return api; ds@3104: } ds@3104: skamonkey@3401: bool SourceModBase::IsMapRunning() skamonkey@3401: { skamonkey@3401: return g_OnMapStarted; skamonkey@3401: } skamonkey@3401: dvander@211: SMGlobalClass *SMGlobalClass::head = NULL; dvander@211: