1.1 --- a/core/sourcemod.cpp Fri Jul 11 06:51:21 2008 +0000
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,647 +0,0 @@
1.4 -/**
1.5 - * vim: set ts=4 :
1.6 - * =============================================================================
1.7 - * SourceMod
1.8 - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
1.9 - * =============================================================================
1.10 - *
1.11 - * This program is free software; you can redistribute it and/or modify it under
1.12 - * the terms of the GNU General Public License, version 3.0, as published by the
1.13 - * Free Software Foundation.
1.14 - *
1.15 - * This program is distributed in the hope that it will be useful, but WITHOUT
1.16 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
1.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
1.18 - * details.
1.19 - *
1.20 - * You should have received a copy of the GNU General Public License along with
1.21 - * this program. If not, see <http://www.gnu.org/licenses/>.
1.22 - *
1.23 - * As a special exception, AlliedModders LLC gives you permission to link the
1.24 - * code of this program (as well as its derivative works) to "Half-Life 2," the
1.25 - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
1.26 - * by the Valve Corporation. You must obey the GNU General Public License in
1.27 - * all respects for all other code used. Additionally, AlliedModders LLC grants
1.28 - * this exception to all derivative works. AlliedModders LLC defines further
1.29 - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
1.30 - * or <http://www.sourcemod.net/license.php>.
1.31 - *
1.32 - * Version: $Id$
1.33 - */
1.34 -
1.35 -#include <stdio.h>
1.36 -#include "sourcemod.h"
1.37 -#include "sourcemm_api.h"
1.38 -#include "systems/LibrarySys.h"
1.39 -#include <sh_string.h>
1.40 -#include "PluginSys.h"
1.41 -#include "ShareSys.h"
1.42 -#include "CoreConfig.h"
1.43 -#include "Logger.h"
1.44 -#include "ExtensionSys.h"
1.45 -#include "AdminCache.h"
1.46 -#include "sm_stringutil.h"
1.47 -#include "PlayerManager.h"
1.48 -#include "Translator.h"
1.49 -#include "ForwardSys.h"
1.50 -#include "TimerSys.h"
1.51 -#include "GameConfigs.h"
1.52 -#include "DebugReporter.h"
1.53 -#include "Profiler.h"
1.54 -
1.55 -SH_DECL_HOOK6(IServerGameDLL, LevelInit, SH_NOATTRIB, false, bool, const char *, const char *, const char *, const char *, bool, bool);
1.56 -SH_DECL_HOOK0_void(IServerGameDLL, LevelShutdown, SH_NOATTRIB, false);
1.57 -SH_DECL_HOOK1_void(IServerGameDLL, GameFrame, SH_NOATTRIB, false, bool);
1.58 -SH_DECL_HOOK1_void(IVEngineServer, ServerCommand, SH_NOATTRIB, false, const char *);
1.59 -
1.60 -SourceModBase g_SourceMod;
1.61 -
1.62 -ILibrary *g_pJIT = NULL;
1.63 -SourceHook::String g_BaseDir;
1.64 -ISourcePawnEngine *g_pSourcePawn = NULL;
1.65 -ISourcePawnEngine2 *g_pSourcePawn2 = NULL;
1.66 -IdentityToken_t *g_pCoreIdent = NULL;
1.67 -IForward *g_pOnMapEnd = NULL;
1.68 -bool g_Loaded = false;
1.69 -
1.70 -typedef ISourcePawnEngine *(*GET_SP_V1)();
1.71 -typedef ISourcePawnEngine2 *(*GET_SP_V2)();
1.72 -typedef void (*NOTIFYSHUTDOWN)();
1.73 -
1.74 -void ShutdownJIT()
1.75 -{
1.76 - NOTIFYSHUTDOWN notify = (NOTIFYSHUTDOWN)g_pJIT->GetSymbolAddress("NotifyShutdown");
1.77 - if (notify)
1.78 - {
1.79 - notify();
1.80 - }
1.81 -
1.82 - g_pJIT->CloseLibrary();
1.83 -}
1.84 -
1.85 -SourceModBase::SourceModBase()
1.86 -{
1.87 - m_IsMapLoading = false;
1.88 - m_ExecPluginReload = false;
1.89 - m_GotBasePath = false;
1.90 -}
1.91 -
1.92 -ConfigResult SourceModBase::OnSourceModConfigChanged(const char *key,
1.93 - const char *value,
1.94 - ConfigSource source,
1.95 - char *error,
1.96 - size_t maxlength)
1.97 -{
1.98 - if (strcasecmp(key, "BasePath") == 0)
1.99 - {
1.100 - if (source == ConfigSource_Console)
1.101 - {
1.102 - UTIL_Format(error, maxlength, "Cannot be set at runtime");
1.103 - return ConfigResult_Reject;
1.104 - }
1.105 -
1.106 - if (!m_GotBasePath)
1.107 - {
1.108 - g_LibSys.PathFormat(m_SMBaseDir, sizeof(m_SMBaseDir), "%s/%s", g_BaseDir.c_str(), value);
1.109 - g_LibSys.PathFormat(m_SMRelDir, sizeof(m_SMRelDir), value);
1.110 -
1.111 - m_GotBasePath = true;
1.112 - }
1.113 -
1.114 - return ConfigResult_Accept;
1.115 - }
1.116 -
1.117 - return ConfigResult_Ignore;
1.118 -}
1.119 -
1.120 -bool SourceModBase::InitializeSourceMod(char *error, size_t maxlength, bool late)
1.121 -{
1.122 - const char *gamepath = g_SMAPI->GetBaseDir();
1.123 -
1.124 - /* Store full path to game */
1.125 - g_BaseDir.assign(gamepath);
1.126 -
1.127 - /* Store name of game directory by itself */
1.128 - size_t len = strlen(gamepath);
1.129 - for (size_t i = len - 1; i >= 0; i--)
1.130 - {
1.131 - if (gamepath[i] == PLATFORM_SEP_CHAR)
1.132 - {
1.133 - strncopy(m_ModDir, &gamepath[++i], sizeof(m_ModDir));
1.134 - break;
1.135 - }
1.136 - }
1.137 -
1.138 - /* Initialize CoreConfig so we can get SourceMod base path properly - this basically parses core.cfg */
1.139 - g_CoreConfig.Initialize();
1.140 -
1.141 - /* This shouldn't happen, but can't hurt to be safe */
1.142 - if (!g_LibSys.PathExists(m_SMBaseDir) || !m_GotBasePath)
1.143 - {
1.144 - g_LibSys.PathFormat(m_SMBaseDir, sizeof(m_SMBaseDir), "%s/addons/sourcemod", g_BaseDir.c_str());
1.145 - g_LibSys.PathFormat(m_SMRelDir, sizeof(m_SMRelDir), "addons/sourcemod");
1.146 - m_GotBasePath = true;
1.147 - }
1.148 -
1.149 - /* Attempt to load the JIT! */
1.150 - char file[PLATFORM_MAX_PATH];
1.151 - char myerror[255];
1.152 - g_SMAPI->PathFormat(file, sizeof(file), "%s/bin/sourcepawn.jit.x86.%s",
1.153 - GetSourceModPath(),
1.154 - PLATFORM_LIB_EXT
1.155 - );
1.156 -
1.157 - g_pJIT = g_LibSys.OpenLibrary(file, myerror, sizeof(myerror));
1.158 - if (!g_pJIT)
1.159 - {
1.160 - if (error && maxlength)
1.161 - {
1.162 - snprintf(error, maxlength, "%s (failed to load bin/sourcepawn.jit.x86.%s)",
1.163 - myerror,
1.164 - PLATFORM_LIB_EXT);
1.165 - }
1.166 - return false;
1.167 - }
1.168 -
1.169 - GET_SP_V1 getv1 = (GET_SP_V1)g_pJIT->GetSymbolAddress("GetSourcePawnEngine1");
1.170 - GET_SP_V2 getv2 = (GET_SP_V2)g_pJIT->GetSymbolAddress("GetSourcePawnEngine2");
1.171 -
1.172 - if (getv1 == NULL)
1.173 - {
1.174 - if (error && maxlength)
1.175 - {
1.176 - snprintf(error, maxlength, "JIT is too old; upgrade SourceMod");
1.177 - }
1.178 - ShutdownJIT();
1.179 - return false;
1.180 - }
1.181 - else if (getv2 == NULL)
1.182 - {
1.183 - if (error && maxlength)
1.184 - {
1.185 - snprintf(error, maxlength, "JIT is too old; upgrade SourceMod");
1.186 - }
1.187 - ShutdownJIT();
1.188 - return false;
1.189 - }
1.190 -
1.191 - g_pSourcePawn = getv1();
1.192 - g_pSourcePawn2 = getv2();
1.193 -
1.194 - g_pSourcePawn2->SetDebugListener(&g_DbgReporter);
1.195 - g_pSourcePawn2->SetProfiler(&g_Profiler);
1.196 -
1.197 - /* Hook this now so we can detect startup without calling StartSourceMod() */
1.198 - SH_ADD_HOOK_MEMFUNC(IServerGameDLL, LevelInit, gamedll, this, &SourceModBase::LevelInit, false);
1.199 -
1.200 - /* Only load if we're not late */
1.201 - if (!late)
1.202 - {
1.203 - StartSourceMod(false);
1.204 - }
1.205 -
1.206 - return true;
1.207 -}
1.208 -
1.209 -void SourceModBase::StartSourceMod(bool late)
1.210 -{
1.211 - SH_ADD_HOOK_MEMFUNC(IServerGameDLL, LevelShutdown, gamedll, this, &SourceModBase::LevelShutdown, false);
1.212 - SH_ADD_HOOK_MEMFUNC(IServerGameDLL, GameFrame, gamedll, &g_Timers, &TimerSystem::GameFrame, false);
1.213 -
1.214 - enginePatch = SH_GET_CALLCLASS(engine);
1.215 - gamedllPatch = SH_GET_CALLCLASS(gamedll);
1.216 -
1.217 - g_ShareSys.Initialize();
1.218 -
1.219 - /* Make the global core identity */
1.220 - g_pCoreIdent = g_ShareSys.CreateCoreIdentity();
1.221 -
1.222 - /* Notify! */
1.223 - SMGlobalClass *pBase = SMGlobalClass::head;
1.224 - while (pBase)
1.225 - {
1.226 - pBase->OnSourceModStartup(false);
1.227 - pBase = pBase->m_pGlobalClassNext;
1.228 - }
1.229 -
1.230 - /* Notify! */
1.231 - pBase = SMGlobalClass::head;
1.232 - while (pBase)
1.233 - {
1.234 - pBase->OnSourceModAllInitialized();
1.235 - pBase = pBase->m_pGlobalClassNext;
1.236 - }
1.237 -
1.238 - /* Notify! */
1.239 - pBase = SMGlobalClass::head;
1.240 - while (pBase)
1.241 - {
1.242 - pBase->OnSourceModAllInitialized_Post();
1.243 - pBase = pBase->m_pGlobalClassNext;
1.244 - }
1.245 -
1.246 - /* Add us now... */
1.247 - g_ShareSys.AddInterface(NULL, this);
1.248 -
1.249 - /* We're loaded! */
1.250 - g_Loaded = true;
1.251 -
1.252 - /* Initialize VSP stuff */
1.253 - if (vsp_interface != NULL)
1.254 - {
1.255 - g_SourceMod_Core.OnVSPListening(vsp_interface);
1.256 - }
1.257 -}
1.258 -
1.259 -static bool g_LevelEndBarrier = false;
1.260 -bool SourceModBase::LevelInit(char const *pMapName, char const *pMapEntities, char const *pOldLevel, char const *pLandmarkName, bool loadGame, bool background)
1.261 -{
1.262 - /* If we're not loaded... */
1.263 - if (!g_Loaded)
1.264 - {
1.265 - /* Do all global initialization now */
1.266 - StartSourceMod(true);
1.267 - }
1.268 -
1.269 - m_IsMapLoading = true;
1.270 - m_ExecPluginReload = true;
1.271 -
1.272 - /* Notify! */
1.273 - SMGlobalClass *pBase = SMGlobalClass::head;
1.274 - while (pBase)
1.275 - {
1.276 - pBase->OnSourceModLevelChange(pMapName);
1.277 - pBase = pBase->m_pGlobalClassNext;
1.278 - }
1.279 -
1.280 - DoGlobalPluginLoads();
1.281 -
1.282 - m_IsMapLoading = false;
1.283 -
1.284 - /* Notify! */
1.285 - pBase = SMGlobalClass::head;
1.286 - while (pBase)
1.287 - {
1.288 - pBase->OnSourceModPluginsLoaded();
1.289 - pBase = pBase->m_pGlobalClassNext;
1.290 - }
1.291 -
1.292 - if (!g_pOnMapEnd)
1.293 - {
1.294 - g_pOnMapEnd = g_Forwards.CreateForward("OnMapEnd", ET_Ignore, 0, NULL);
1.295 - }
1.296 -
1.297 - g_LevelEndBarrier = true;
1.298 -
1.299 - RETURN_META_VALUE(MRES_IGNORED, true);
1.300 -}
1.301 -
1.302 -void SourceModBase::LevelShutdown()
1.303 -{
1.304 - if (g_LevelEndBarrier)
1.305 - {
1.306 - SMGlobalClass *next = SMGlobalClass::head;
1.307 - while (next)
1.308 - {
1.309 - next->OnSourceModLevelEnd();
1.310 - next = next->m_pGlobalClassNext;
1.311 - }
1.312 -
1.313 - if (g_pOnMapEnd != NULL)
1.314 - {
1.315 - g_pOnMapEnd->Execute(NULL);
1.316 - }
1.317 -
1.318 - g_Timers.RemoveMapChangeTimers();
1.319 -
1.320 - g_LevelEndBarrier = false;
1.321 - }
1.322 -
1.323 - g_OnMapStarted = false;
1.324 -
1.325 - if (m_ExecPluginReload)
1.326 - {
1.327 - g_PluginSys.ReloadOrUnloadPlugins();
1.328 - m_ExecPluginReload = false;
1.329 - }
1.330 -}
1.331 -
1.332 -bool SourceModBase::IsMapLoading() const
1.333 -{
1.334 - return m_IsMapLoading;
1.335 -}
1.336 -
1.337 -void SourceModBase::DoGlobalPluginLoads()
1.338 -{
1.339 - char config_path[PLATFORM_MAX_PATH];
1.340 - char plugins_path[PLATFORM_MAX_PATH];
1.341 -
1.342 - BuildPath(Path_SM, config_path,
1.343 - sizeof(config_path),
1.344 - "configs/plugin_settings.cfg");
1.345 - BuildPath(Path_SM, plugins_path,
1.346 - sizeof(plugins_path),
1.347 - "plugins");
1.348 -
1.349 - /* Load any auto extensions */
1.350 - g_Extensions.TryAutoload();
1.351 -
1.352 - /* Fire the extensions ready message */
1.353 - g_SMAPI->MetaFactory(SOURCEMOD_NOTICE_EXTENSIONS, NULL, NULL);
1.354 -
1.355 - /* Load any game extension */
1.356 - const char *game_ext;
1.357 - if ((game_ext = g_pGameConf->GetKeyValue("GameExtension")) != NULL)
1.358 - {
1.359 - char path[PLATFORM_MAX_PATH];
1.360 - UTIL_Format(path, sizeof(path), "%s.ext." PLATFORM_LIB_EXT, game_ext);
1.361 - g_Extensions.LoadAutoExtension(path);
1.362 - }
1.363 -
1.364 - /* Run the first pass */
1.365 - g_PluginSys.LoadAll_FirstPass(config_path, plugins_path);
1.366 -
1.367 - /* Mark any extensions as loaded */
1.368 - g_Extensions.MarkAllLoaded();
1.369 -
1.370 - /* No modules yet, it's safe to call this from here */
1.371 - g_PluginSys.LoadAll_SecondPass();
1.372 -
1.373 - /* Re-mark any extensions as loaded */
1.374 - g_Extensions.MarkAllLoaded();
1.375 -
1.376 - /* Call OnAllPluginsLoaded */
1.377 - g_PluginSys.AllPluginsLoaded();
1.378 -}
1.379 -
1.380 -size_t SourceModBase::BuildPath(PathType type, char *buffer, size_t maxlength, const char *format, ...)
1.381 -{
1.382 - char _buffer[PLATFORM_MAX_PATH];
1.383 - va_list ap;
1.384 -
1.385 - va_start(ap, format);
1.386 - vsnprintf(_buffer, PLATFORM_MAX_PATH, format, ap);
1.387 - va_end(ap);
1.388 -
1.389 - /* If we get a "file://" notation, strip off the file:// part so we're left
1.390 - * with an absolute path. Note that the absolute path gets returned, so
1.391 - * usage with relative paths here is completely invalid.
1.392 - */
1.393 - if (type != Path_SM_Rel && strncmp(_buffer, "file://", 7) == 0)
1.394 - {
1.395 - return g_LibSys.PathFormat(buffer, maxlength, "%s", &_buffer[7]);
1.396 - }
1.397 -
1.398 - const char *base = NULL;
1.399 - if (type == Path_Game)
1.400 - {
1.401 - base = GetGamePath();
1.402 - }
1.403 - else if (type == Path_SM)
1.404 - {
1.405 - base = GetSourceModPath();
1.406 - }
1.407 - else if (type == Path_SM_Rel)
1.408 - {
1.409 - base = m_SMRelDir;
1.410 - }
1.411 -
1.412 - if (base)
1.413 - {
1.414 - return g_LibSys.PathFormat(buffer, maxlength, "%s/%s", base, _buffer);
1.415 - }
1.416 - else
1.417 - {
1.418 - return g_LibSys.PathFormat(buffer, maxlength, "%s", _buffer);
1.419 - }
1.420 -}
1.421 -
1.422 -void SourceModBase::CloseSourceMod()
1.423 -{
1.424 - /* Force a level end */
1.425 - LevelShutdown();
1.426 -
1.427 - /* Unload plugins */
1.428 - g_PluginSys.Shutdown();
1.429 -
1.430 - /* Unload extensions */
1.431 - g_Extensions.Shutdown();
1.432 -
1.433 - SH_REMOVE_HOOK_MEMFUNC(IServerGameDLL, LevelInit, gamedll, this, &SourceModBase::LevelInit, false);
1.434 -
1.435 - if (g_Loaded)
1.436 - {
1.437 - if (g_pOnMapEnd)
1.438 - {
1.439 - g_Forwards.ReleaseForward(g_pOnMapEnd);
1.440 - }
1.441 -
1.442 - /* Notify! */
1.443 - SMGlobalClass *pBase = SMGlobalClass::head;
1.444 - while (pBase)
1.445 - {
1.446 - pBase->OnSourceModShutdown();
1.447 - pBase = pBase->m_pGlobalClassNext;
1.448 - }
1.449 -
1.450 - /* Delete all data packs */
1.451 - CStack<CDataPack *>::iterator iter;
1.452 - CDataPack *pd;
1.453 - for (iter=m_freepacks.begin(); iter!=m_freepacks.end(); iter++)
1.454 - {
1.455 - pd = (*iter);
1.456 - delete pd;
1.457 - }
1.458 - m_freepacks.popall();
1.459 -
1.460 - /* Notify! */
1.461 - pBase = SMGlobalClass::head;
1.462 - while (pBase)
1.463 - {
1.464 - pBase->OnSourceModAllShutdown();
1.465 - pBase = pBase->m_pGlobalClassNext;
1.466 - }
1.467 -
1.468 - if (enginePatch)
1.469 - {
1.470 - SH_RELEASE_CALLCLASS(enginePatch);
1.471 - enginePatch = NULL;
1.472 - }
1.473 -
1.474 - if (gamedllPatch)
1.475 - {
1.476 - SH_RELEASE_CALLCLASS(gamedllPatch);
1.477 - gamedllPatch = NULL;
1.478 - }
1.479 -
1.480 - SH_REMOVE_HOOK_MEMFUNC(IServerGameDLL, LevelShutdown, gamedll, this, &SourceModBase::LevelShutdown, false);
1.481 - SH_REMOVE_HOOK_MEMFUNC(IServerGameDLL, GameFrame, gamedll, &g_Timers, &TimerSystem::GameFrame, false);
1.482 - }
1.483 -
1.484 - /* Rest In Peace */
1.485 - ShutdownJIT();
1.486 -}
1.487 -
1.488 -void SourceModBase::LogMessage(IExtension *pExt, const char *format, ...)
1.489 -{
1.490 - IExtensionInterface *pAPI = pExt->GetAPI();
1.491 - const char *tag = pAPI->GetExtensionTag();
1.492 - char buffer[2048];
1.493 - va_list ap;
1.494 -
1.495 - va_start(ap, format);
1.496 - vsnprintf(buffer, sizeof(buffer), format, ap);
1.497 - va_end(ap);
1.498 -
1.499 - if (tag)
1.500 - {
1.501 - g_Logger.LogMessage("[%s] %s", tag, buffer);
1.502 - } else {
1.503 - g_Logger.LogMessage("%s", buffer);
1.504 - }
1.505 -}
1.506 -
1.507 -void SourceModBase::LogError(IExtension *pExt, const char *format, ...)
1.508 -{
1.509 - IExtensionInterface *pAPI = pExt->GetAPI();
1.510 - const char *tag = pAPI->GetExtensionTag();
1.511 - char buffer[2048];
1.512 - va_list ap;
1.513 -
1.514 - va_start(ap, format);
1.515 - vsnprintf(buffer, sizeof(buffer), format, ap);
1.516 - va_end(ap);
1.517 -
1.518 - if (tag)
1.519 - {
1.520 - g_Logger.LogError("[%s] %s", tag, buffer);
1.521 - } else {
1.522 - g_Logger.LogError("%s", buffer);
1.523 - }
1.524 -}
1.525 -
1.526 -size_t SourceModBase::FormatString(char *buffer, size_t maxlength, IPluginContext *pContext, const cell_t *params, unsigned int param)
1.527 -{
1.528 - char *fmt;
1.529 -
1.530 - pContext->LocalToString(params[param], &fmt);
1.531 -
1.532 - int lparam = ++param;
1.533 -
1.534 - return atcprintf(buffer, maxlength, fmt, pContext, params, &lparam);
1.535 -}
1.536 -
1.537 -const char *SourceModBase::GetSourceModPath() const
1.538 -{
1.539 - return m_SMBaseDir;
1.540 -}
1.541 -
1.542 -const char *SourceModBase::GetGamePath() const
1.543 -{
1.544 - return g_BaseDir.c_str();
1.545 -}
1.546 -
1.547 -unsigned int SourceModBase::SetGlobalTarget(unsigned int index)
1.548 -{
1.549 - unsigned int old = m_target;
1.550 - m_target = index;
1.551 - return old;
1.552 -}
1.553 -
1.554 -unsigned int SourceModBase::GetGlobalTarget() const
1.555 -{
1.556 - return m_target;
1.557 -}
1.558 -
1.559 -IDataPack *SourceModBase::CreateDataPack()
1.560 -{
1.561 - CDataPack *pack;
1.562 - if (m_freepacks.empty())
1.563 - {
1.564 - pack = new CDataPack;
1.565 - } else {
1.566 - pack = m_freepacks.front();
1.567 - m_freepacks.pop();
1.568 - pack->Initialize();
1.569 - }
1.570 - return pack;
1.571 -}
1.572 -
1.573 -void SourceModBase::FreeDataPack(IDataPack *pack)
1.574 -{
1.575 - m_freepacks.push(static_cast<CDataPack *>(pack));
1.576 -}
1.577 -
1.578 -Handle_t SourceModBase::GetDataPackHandleType(bool readonly)
1.579 -{
1.580 - //:TODO:
1.581 - return 0;
1.582 -}
1.583 -
1.584 -const char *SourceModBase::GetGameFolderName() const
1.585 -{
1.586 - return m_ModDir;
1.587 -}
1.588 -
1.589 -ISourcePawnEngine *SourceModBase::GetScriptingEngine()
1.590 -{
1.591 - return g_pSourcePawn;
1.592 -}
1.593 -
1.594 -IVirtualMachine *SourceModBase::GetScriptingVM()
1.595 -{
1.596 - return NULL;
1.597 -}
1.598 -
1.599 -void SourceModBase::AllPluginsLoaded()
1.600 -{
1.601 - SMGlobalClass *base = SMGlobalClass::head;
1.602 - while (base)
1.603 - {
1.604 - base->OnSourceModGameInitialized();
1.605 - base = base->m_pGlobalClassNext;
1.606 - }
1.607 -}
1.608 -
1.609 -time_t SourceModBase::GetAdjustedTime()
1.610 -{
1.611 - return ::GetAdjustedTime();
1.612 -}
1.613 -
1.614 -void SourceModBase::AddGameFrameHook(GAME_FRAME_HOOK hook)
1.615 -{
1.616 - m_frame_hooks.push_back(hook);
1.617 -}
1.618 -
1.619 -void SourceModBase::RemoveGameFrameHook(GAME_FRAME_HOOK hook)
1.620 -{
1.621 - for (size_t i = 0; i < m_frame_hooks.size(); i++)
1.622 - {
1.623 - if (m_frame_hooks[i] == hook)
1.624 - {
1.625 - m_frame_hooks.erase(m_frame_hooks.iterAt(i));
1.626 - return;
1.627 - }
1.628 - }
1.629 -}
1.630 -
1.631 -void SourceModBase::ProcessGameFrameHooks(bool simulating)
1.632 -{
1.633 - if (m_frame_hooks.size() == 0)
1.634 - {
1.635 - return;
1.636 - }
1.637 -
1.638 - for (size_t i = 0; i < m_frame_hooks.size(); i++)
1.639 - {
1.640 - m_frame_hooks[i](simulating);
1.641 - }
1.642 -}
1.643 -
1.644 -SMGlobalClass *SMGlobalClass::head = NULL;
1.645 -
1.646 -SMGlobalClass::SMGlobalClass()
1.647 -{
1.648 - m_pGlobalClassNext = SMGlobalClass::head;
1.649 - SMGlobalClass::head = this;
1.650 -}