diff --git a/core/msvc8/sourcemod_mm.vcproj b/core/msvc8/sourcemod_mm.vcproj index 1e9d4c52..53913af5 100644 --- a/core/msvc8/sourcemod_mm.vcproj +++ b/core/msvc8/sourcemod_mm.vcproj @@ -40,7 +40,7 @@ + + + + @@ -213,12 +221,6 @@ > - - @@ -410,6 +412,12 @@ > + + diff --git a/core/sm_globals.h b/core/sm_globals.h new file mode 100644 index 00000000..b89637b7 --- /dev/null +++ b/core/sm_globals.h @@ -0,0 +1,15 @@ +#ifndef _INCLUDE_SOURCEMOD_GLOBALS_H_ +#define _INCLUDE_SOURCEMOD_GLOBALS_H_ + +#include +#include +#include "sm_platform.h" +#include "interfaces/IShareSys.h" + +using namespace SourcePawn; +using namespace SourceMod; + +extern ISourcePawnEngine *g_pSourcePawn; +extern IVirtualMachine *g_pVM; + +#endif //_INCLUDE_SOURCEMOD_GLOBALS_H_ diff --git a/core/sm_platform.h b/core/sm_platform.h index eca8070c..c313d084 100644 --- a/core/sm_platform.h +++ b/core/sm_platform.h @@ -11,6 +11,7 @@ #endif #include #include +#define PLATFORM_LIB_EXT "dll" #define PLATFORM_MAX_PATH MAX_PATH #else if defined __linux__ #define PLATFORM_LINUX @@ -18,6 +19,7 @@ #include #include #define PLATFORM_MAX_PATH PATH_MAX +#define PLATFORM_LIB_EXT "so" #endif #endif //_INCLUDE_SOURCEMOD_PLATFORM_H_ diff --git a/core/sourcemm_api.cpp b/core/sourcemm_api.cpp index 83c871d2..2e862a26 100644 --- a/core/sourcemm_api.cpp +++ b/core/sourcemm_api.cpp @@ -1,17 +1,17 @@ #include #include "sourcemm_api.h" #include "sm_version.h" -#include "CTextParsers.h" +#include "sourcemod.h" -SourceMod_Core g_SourceMod; +SourceMod_Core g_SourceMod_Core; -PLUGIN_EXPOSE(SourceMod, g_SourceMod); +PLUGIN_EXPOSE(SourceMod, g_SourceMod_Core); bool SourceMod_Core::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen, bool late) { PLUGIN_SAVEVARS(); - return true; + return g_SourceMod.InitializeSourceMod(error, maxlen, late); } bool SourceMod_Core::Unload(char *error, size_t maxlen) diff --git a/core/sourcemm_api.h b/core/sourcemm_api.h index 5b230f39..002416fc 100644 --- a/core/sourcemm_api.h +++ b/core/sourcemm_api.h @@ -22,7 +22,7 @@ public: const char *GetLogTag(); }; -extern SourceMod_Core g_SourceMod; +extern SourceMod_Core g_SourceMod_Core; PLUGIN_GLOBALVARS(); diff --git a/core/sourcemod.cpp b/core/sourcemod.cpp new file mode 100644 index 00000000..69f81f2a --- /dev/null +++ b/core/sourcemod.cpp @@ -0,0 +1,103 @@ +#include +#include "sourcemod.h" +#include "sourcemm_api.h" +#include "systems/LibrarySys.h" +#include "vm/sp_vm_engine.h" +#include + +SourcePawnEngine g_SourcePawn; +SourceModBase g_SourceMod; + +ILibrary *g_pJIT = NULL; +SourceHook::String g_BaseDir; +ISourcePawnEngine *g_pSourcePawn = &g_SourcePawn; +IVirtualMachine *g_pVM; + +typedef int (*GIVEENGINEPOINTER)(ISourcePawnEngine *); +typedef unsigned int (*GETEXPORTCOUNT)(); +typedef IVirtualMachine *(*GETEXPORT)(unsigned int); +typedef void (*NOTIFYSHUTDOWN)(); + +void ShutdownJIT() +{ + NOTIFYSHUTDOWN notify = (NOTIFYSHUTDOWN)g_pJIT->GetSymbolAddress("NotifyShutdown"); + if (notify) + { + notify(); + } + + g_pJIT->CloseLibrary(); +} + +bool SourceModBase::InitializeSourceMod(char *error, size_t err_max, bool late) +{ + //:TODO: we need a localinfo system! + g_BaseDir.assign(g_SMAPI->GetBaseDir()); + + /* Attempt to load the JIT! */ + char file[PLATFORM_MAX_PATH]; + char myerror[255]; + g_SMAPI->PathFormat(file, sizeof(file), "%s/addons/sourcemod/bin/sourcepawn.jit.x86.%s", + g_BaseDir.c_str(), + PLATFORM_LIB_EXT + ); + + g_pJIT = g_LibSys.OpenLibrary(file, myerror, sizeof(myerror)); + if (!g_pJIT) + { + if (error && err_max) + { + snprintf(error, err_max, "%s (failed to load bin/sourcepawn.jit.x86.%s)", + myerror, + PLATFORM_LIB_EXT); + } + return false; + } + + int err; + GIVEENGINEPOINTER jit_init = (GIVEENGINEPOINTER)g_pJIT->GetSymbolAddress("GiveEnginePointer"); + if (!jit_init) + { + ShutdownJIT(); + if (error && err_max) + { + snprintf(error, err_max, "Failed to find GiveEnginePointer in JIT!"); + } + return false; + } + + if ((err=jit_init(g_pSourcePawn)) != 0) + { + ShutdownJIT(); + if (error && err_max) + { + snprintf(error, err_max, "GiveEnginePointer returned %d in the JIT", err); + } + return false; + } + + GETEXPORTCOUNT jit_getnum = (GETEXPORTCOUNT)g_pJIT->GetSymbolAddress("GetExportCount"); + GETEXPORT jit_get = (GETEXPORT)g_pJIT->GetSymbolAddress("GetExport"); + if (!jit_get) + { + ShutdownJIT(); + if (error && err_max) + { + snprintf(error, err_max, "JIT is missing a necessary export!"); + } + return false; + } + + unsigned int num = jit_getnum(); + if (!num || ((g_pVM=jit_get(0)) == NULL)) + { + ShutdownJIT(); + if (error && err_max) + { + snprintf(error, err_max, "JIT did not export any virtual machines!"); + } + return false; + } + + return true; +} diff --git a/core/sourcemod.h b/core/sourcemod.h index deadb72f..143a96ca 100644 --- a/core/sourcemod.h +++ b/core/sourcemod.h @@ -1,8 +1,17 @@ #ifndef _INCLUDE_SOURCEMOD_GLOBALHEADER_H_ #define _INCLUDE_SOURCEMOD_GLOBALHEADER_H_ -#include -#include +#include "sm_globals.h" +class SourceModBase +{ +public: + /** + * @brief Initializes SourceMod, or returns an error on failure. + */ + bool InitializeSourceMod(char *error, size_t err_max, bool late); +}; + +extern SourceModBase g_SourceMod; #endif //_INCLUDE_SOURCEMOD_GLOBALHEADER_H_