3 #include "sourcemm_api.h"
4 #include "systems/LibrarySys.h"
5 #include "vm/sp_vm_engine.h"
8 #include "ForwardSys.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;
20 typedef int (*GIVEENGINEPOINTER)(ISourcePawnEngine *);
21 typedef unsigned int (*GETEXPORTCOUNT)();
22 typedef IVirtualMachine *(*GETEXPORT)(unsigned int);
23 typedef void (*NOTIFYSHUTDOWN)();
27 NOTIFYSHUTDOWN notify = (NOTIFYSHUTDOWN)g_pJIT->GetSymbolAddress("NotifyShutdown");
33 g_pJIT->CloseLibrary();
36 SourceModBase::SourceModBase()
38 m_IsMapLoading = false;
41 bool SourceModBase::InitializeSourceMod(char *error, size_t err_max, bool late)
43 g_BaseDir.assign(g_SMAPI->GetBaseDir());
44 g_LibSys.PathFormat(m_SMBaseDir, sizeof(m_SMBaseDir), "%s/addons/sourcemod", g_BaseDir.c_str());
46 /* Attempt to load the JIT! */
47 char file[PLATFORM_MAX_PATH];
49 g_SMAPI->PathFormat(file, sizeof(file), "%s/bin/sourcepawn.jit.x86.%s",
54 g_pJIT = g_LibSys.OpenLibrary(file, myerror, sizeof(myerror));
59 snprintf(error, err_max, "%s (failed to load bin/sourcepawn.jit.x86.%s)",
67 GIVEENGINEPOINTER jit_init = (GIVEENGINEPOINTER)g_pJIT->GetSymbolAddress("GiveEnginePointer");
73 snprintf(error, err_max, "Failed to find GiveEnginePointer in JIT!");
78 if ((err=jit_init(g_pSourcePawn)) != 0)
83 snprintf(error, err_max, "GiveEnginePointer returned %d in the JIT", err);
88 GETEXPORTCOUNT jit_getnum = (GETEXPORTCOUNT)g_pJIT->GetSymbolAddress("GetExportCount");
89 GETEXPORT jit_get = (GETEXPORT)g_pJIT->GetSymbolAddress("GetExport");
95 snprintf(error, err_max, "JIT is missing a necessary export!");
100 unsigned int num = jit_getnum();
101 if (!num || ((g_pVM=jit_get(0)) == NULL))
104 if (error && err_max)
106 snprintf(error, err_max, "JIT did not export any virtual machines!");
111 unsigned int api = g_pVM->GetAPIVersion();
112 if (api != SOURCEPAWN_VM_API_VERSION)
115 if (error && err_max)
117 snprintf(error, err_max, "JIT is not a compatible version");
122 StartSourceMod(late);
127 void SourceModBase::StartSourceMod(bool late)
129 /* First initialize the global hooks we need */
130 SH_ADD_HOOK_MEMFUNC(IServerGameDLL, LevelInit, gamedll, this, &SourceModBase::LevelInit, false);
132 /* If we're late, automatically load plugins now */
135 m_IsLateLoadInMap = late;
136 DoGlobalPluginLoads();
140 bool SourceModBase::LevelInit(char const *pMapName, char const *pMapEntities, char const *pOldLevel, char const *pLandmarkName, bool loadGame, bool background)
142 m_IsMapLoading = true;
143 m_IsLateLoadInMap = false;
145 DoGlobalPluginLoads();
147 m_IsMapLoading = false;
149 RETURN_META_VALUE(MRES_IGNORED, true);
152 void SourceModBase::DoGlobalPluginLoads()
154 char config_path[PLATFORM_MAX_PATH];
155 char plugins_path[PLATFORM_MAX_PATH];
157 g_SMAPI->PathFormat(config_path,
159 "%s/configs/plugin_settings.cfg",
161 g_SMAPI->PathFormat(plugins_path,
162 sizeof(plugins_path),
166 g_PluginSys.LoadAll_FirstPass(config_path, plugins_path);
168 /* No modules yet, it's safe to call this from here */
169 g_PluginSys.LoadAll_SecondPass();
172 bool SourceModBase::IsLateLoadInMap()
174 return m_IsLateLoadInMap;
177 const char *SourceModBase::GetSMBaseDir()
182 SMGlobalClass *SMGlobalClass::head = NULL;
184 SMGlobalClass::SMGlobalClass()
186 m_pGlobalClassNext = SMGlobalClass::head;
187 SMGlobalClass::head = this;