3 #include "sourcemm_api.h"
4 #include "systems/LibrarySys.h"
5 #include "vm/sp_vm_engine.h"
11 SH_DECL_HOOK6(IServerGameDLL, LevelInit, SH_NOATTRIB, false, bool, const char *, const char *, const char *, const char *, bool, bool);
13 SourcePawnEngine g_SourcePawn;
14 SourceModBase g_SourceMod;
16 ILibrary *g_pJIT = NULL;
17 SourceHook::String g_BaseDir;
18 ISourcePawnEngine *g_pSourcePawn = &g_SourcePawn;
19 IVirtualMachine *g_pVM;
20 IdentityToken_t *g_pCoreIdent = NULL;
22 typedef int (*GIVEENGINEPOINTER)(ISourcePawnEngine *);
23 typedef unsigned int (*GETEXPORTCOUNT)();
24 typedef IVirtualMachine *(*GETEXPORT)(unsigned int);
25 typedef void (*NOTIFYSHUTDOWN)();
29 NOTIFYSHUTDOWN notify = (NOTIFYSHUTDOWN)g_pJIT->GetSymbolAddress("NotifyShutdown");
35 g_pJIT->CloseLibrary();
38 SourceModBase::SourceModBase()
40 m_IsMapLoading = false;
43 bool SourceModBase::InitializeSourceMod(char *error, size_t err_max, bool late)
45 g_BaseDir.assign(g_SMAPI->GetBaseDir());
46 g_LibSys.PathFormat(m_SMBaseDir, sizeof(m_SMBaseDir), "%s/addons/sourcemod", g_BaseDir.c_str());
48 /* Attempt to load the JIT! */
49 char file[PLATFORM_MAX_PATH];
51 g_SMAPI->PathFormat(file, sizeof(file), "%s/bin/sourcepawn.jit.x86.%s",
56 g_pJIT = g_LibSys.OpenLibrary(file, myerror, sizeof(myerror));
61 snprintf(error, err_max, "%s (failed to load bin/sourcepawn.jit.x86.%s)",
69 GIVEENGINEPOINTER jit_init = (GIVEENGINEPOINTER)g_pJIT->GetSymbolAddress("GiveEnginePointer");
75 snprintf(error, err_max, "Failed to find GiveEnginePointer in JIT!");
80 if ((err=jit_init(g_pSourcePawn)) != 0)
85 snprintf(error, err_max, "GiveEnginePointer returned %d in the JIT", err);
90 GETEXPORTCOUNT jit_getnum = (GETEXPORTCOUNT)g_pJIT->GetSymbolAddress("GetExportCount");
91 GETEXPORT jit_get = (GETEXPORT)g_pJIT->GetSymbolAddress("GetExport");
97 snprintf(error, err_max, "JIT is missing a necessary export!");
102 unsigned int num = jit_getnum();
103 if (!num || ((g_pVM=jit_get(0)) == NULL))
106 if (error && err_max)
108 snprintf(error, err_max, "JIT did not export any virtual machines!");
113 unsigned int api = g_pVM->GetAPIVersion();
114 if (api != SOURCEPAWN_VM_API_VERSION)
117 if (error && err_max)
119 snprintf(error, err_max, "JIT is not a compatible version");
124 StartSourceMod(late);
129 void SourceModBase::StartSourceMod(bool late)
131 /* First initialize the global hooks we need */
132 SH_ADD_HOOK_MEMFUNC(IServerGameDLL, LevelInit, gamedll, this, &SourceModBase::LevelInit, false);
134 m_IsLateLoadInMap = late;
137 SMGlobalClass *pBase = SMGlobalClass::head;
140 pBase->OnSourceModStartup(m_IsLateLoadInMap);
141 pBase = pBase->m_pGlobalClassNext;
144 /* Make the global core identity */
145 g_pCoreIdent = g_ShareSys.CreateCoreIdentity();
148 pBase = SMGlobalClass::head;
151 pBase->OnSourceModAllInitialized();
152 pBase = pBase->m_pGlobalClassNext;
156 bool SourceModBase::LevelInit(char const *pMapName, char const *pMapEntities, char const *pOldLevel, char const *pLandmarkName, bool loadGame, bool background)
158 m_IsMapLoading = true;
159 m_IsLateLoadInMap = false;
161 g_Logger.MapChange(pMapName);
163 DoGlobalPluginLoads();
165 m_IsMapLoading = false;
167 RETURN_META_VALUE(MRES_IGNORED, true);
170 void SourceModBase::DoGlobalPluginLoads()
172 char config_path[PLATFORM_MAX_PATH];
173 char plugins_path[PLATFORM_MAX_PATH];
175 g_SMAPI->PathFormat(config_path,
177 "%s/configs/plugin_settings.cfg",
179 g_SMAPI->PathFormat(plugins_path,
180 sizeof(plugins_path),
184 g_PluginSys.LoadAll_FirstPass(config_path, plugins_path);
186 /* No modules yet, it's safe to call this from here */
187 g_PluginSys.LoadAll_SecondPass();
190 bool SourceModBase::IsLateLoadInMap()
192 return m_IsLateLoadInMap;
195 const char *SourceModBase::GetSMBaseDir()
200 const char *SourceModBase::GetBaseDir()
202 return g_BaseDir.c_str();
205 SMGlobalClass *SMGlobalClass::head = NULL;
207 SMGlobalClass::SMGlobalClass()
209 m_pGlobalClassNext = SMGlobalClass::head;
210 SMGlobalClass::head = this;