3 #include "sourcemm_api.h"
4 #include "systems/LibrarySys.h"
5 #include "vm/sp_vm_engine.h"
10 SH_DECL_HOOK6(IServerGameDLL, LevelInit, SH_NOATTRIB, false, bool, const char *, const char *, const char *, const char *, bool, bool);
12 SourcePawnEngine g_SourcePawn;
13 SourceModBase g_SourceMod;
15 ILibrary *g_pJIT = NULL;
16 SourceHook::String g_BaseDir;
17 ISourcePawnEngine *g_pSourcePawn = &g_SourcePawn;
18 IVirtualMachine *g_pVM;
19 IdentityToken_t *g_pCoreIdent = NULL;
21 typedef int (*GIVEENGINEPOINTER)(ISourcePawnEngine *);
22 typedef unsigned int (*GETEXPORTCOUNT)();
23 typedef IVirtualMachine *(*GETEXPORT)(unsigned int);
24 typedef void (*NOTIFYSHUTDOWN)();
28 NOTIFYSHUTDOWN notify = (NOTIFYSHUTDOWN)g_pJIT->GetSymbolAddress("NotifyShutdown");
34 g_pJIT->CloseLibrary();
37 SourceModBase::SourceModBase()
39 m_IsMapLoading = false;
42 bool SourceModBase::InitializeSourceMod(char *error, size_t err_max, bool late)
44 g_BaseDir.assign(g_SMAPI->GetBaseDir());
45 g_LibSys.PathFormat(m_SMBaseDir, sizeof(m_SMBaseDir), "%s/addons/sourcemod", g_BaseDir.c_str());
47 /* Attempt to load the JIT! */
48 char file[PLATFORM_MAX_PATH];
50 g_SMAPI->PathFormat(file, sizeof(file), "%s/bin/sourcepawn.jit.x86.%s",
55 g_pJIT = g_LibSys.OpenLibrary(file, myerror, sizeof(myerror));
60 snprintf(error, err_max, "%s (failed to load bin/sourcepawn.jit.x86.%s)",
68 GIVEENGINEPOINTER jit_init = (GIVEENGINEPOINTER)g_pJIT->GetSymbolAddress("GiveEnginePointer");
74 snprintf(error, err_max, "Failed to find GiveEnginePointer in JIT!");
79 if ((err=jit_init(g_pSourcePawn)) != 0)
84 snprintf(error, err_max, "GiveEnginePointer returned %d in the JIT", err);
89 GETEXPORTCOUNT jit_getnum = (GETEXPORTCOUNT)g_pJIT->GetSymbolAddress("GetExportCount");
90 GETEXPORT jit_get = (GETEXPORT)g_pJIT->GetSymbolAddress("GetExport");
96 snprintf(error, err_max, "JIT is missing a necessary export!");
101 unsigned int num = jit_getnum();
102 if (!num || ((g_pVM=jit_get(0)) == NULL))
105 if (error && err_max)
107 snprintf(error, err_max, "JIT did not export any virtual machines!");
112 unsigned int api = g_pVM->GetAPIVersion();
113 if (api != SOURCEPAWN_VM_API_VERSION)
116 if (error && err_max)
118 snprintf(error, err_max, "JIT is not a compatible version");
123 StartSourceMod(late);
128 void SourceModBase::StartSourceMod(bool late)
130 /* First initialize the global hooks we need */
131 SH_ADD_HOOK_MEMFUNC(IServerGameDLL, LevelInit, gamedll, this, &SourceModBase::LevelInit, false);
133 m_IsLateLoadInMap = late;
136 SMGlobalClass *pBase = SMGlobalClass::head;
139 pBase->OnSourceModStartup(m_IsLateLoadInMap);
140 pBase = pBase->m_pGlobalClassNext;
143 /* Make the global core identity */
144 g_pCoreIdent = g_ShareSys.CreateCoreIdentity();
147 pBase = SMGlobalClass::head;
150 pBase->OnSourceModAllInitialized();
151 pBase = pBase->m_pGlobalClassNext;
154 /* If we're late, automatically load plugins now */
157 DoGlobalPluginLoads();
161 bool SourceModBase::LevelInit(char const *pMapName, char const *pMapEntities, char const *pOldLevel, char const *pLandmarkName, bool loadGame, bool background)
163 m_IsMapLoading = true;
164 m_IsLateLoadInMap = false;
166 DoGlobalPluginLoads();
168 m_IsMapLoading = false;
170 RETURN_META_VALUE(MRES_IGNORED, true);
173 void SourceModBase::DoGlobalPluginLoads()
175 char config_path[PLATFORM_MAX_PATH];
176 char plugins_path[PLATFORM_MAX_PATH];
178 g_SMAPI->PathFormat(config_path,
180 "%s/configs/plugin_settings.cfg",
182 g_SMAPI->PathFormat(plugins_path,
183 sizeof(plugins_path),
187 g_PluginSys.LoadAll_FirstPass(config_path, plugins_path);
189 /* No modules yet, it's safe to call this from here */
190 g_PluginSys.LoadAll_SecondPass();
193 bool SourceModBase::IsLateLoadInMap()
195 return m_IsLateLoadInMap;
198 const char *SourceModBase::GetSMBaseDir()
203 const char *SourceModBase::GetBaseDir()
205 return g_BaseDir.c_str();
208 SMGlobalClass *SMGlobalClass::head = NULL;
210 SMGlobalClass::SMGlobalClass()
212 m_pGlobalClassNext = SMGlobalClass::head;
213 SMGlobalClass::head = this;