@@ -26,22 +26,47 @@ extern ILuaModuleManager10 *pModuleManager;
2626
2727int amx_SAMPInit (AMX *amx);
2828
29- typedef int (STDCALL AmxLoad_t) (AMX *);
30- typedef int (STDCALL AmxUnload_t) (AMX *);
31- typedef bool (STDCALL Load_t) (void **);
29+ typedef unsigned int (STDCALL Supports_t) ();
30+ typedef int (STDCALL AmxLoad_t) (AMX *);
31+ typedef int (STDCALL AmxUnload_t) (AMX *);
32+ typedef bool (STDCALL Load_t) (void **);
33+ typedef void (STDCALL Unload_t) ();
34+
35+ #define SAMP_PLUGIN_VERSION 0x0200
36+
37+ enum SUPPORTS_FLAGS
38+ {
39+ SUPPORTS_VERSION = SAMP_PLUGIN_VERSION,
40+ SUPPORTS_VERSION_MASK = 0xffff ,
41+ SUPPORTS_AMX_NATIVES = 0x10000 ,
42+ SUPPORTS_PROCESS_TICK = 0x20000
43+ };
44+
45+ struct SampPlugin
46+ {
47+ HMODULE pPluginPointer = nullptr ;
48+
49+ SUPPORTS_FLAGS dwSupportFlags = (SUPPORTS_FLAGS)0 ;
50+
51+ Unload_t *Unload = nullptr ;
52+
53+ AmxLoad_t *AmxLoad = nullptr ;
54+ AmxUnload_t *AmxUnload = nullptr ;
55+ };
3256
3357extern void *pluginInitData[];
3458extern lua_State *mainVM;
3559
3660map< AMX *, AMXPROPS > loadedAMXs;
3761map< AMX *, map< int , sqlite3 * > > loadedDBs; // amx => (dbID => db)
38- map< string, HMODULE > loadedPlugins;
62+ map< string, SampPlugin* > loadedPlugins;
63+ vector<ProcessTick_t*> vecPfnProcessTick;
3964
4065AMX *suspendedAMX = NULL ;
4166
4267// amxLoadPlugin(pluginName)
4368int CFunctions::amxLoadPlugin (lua_State *luaVM) {
44- static const char *requiredExports[] = { " Load" , " AmxLoad " , " AmxUnload " , " Unload " , 0 };
69+ static const char *requiredExports[] = { " Load" , " Unload " , " Supports " , 0 };
4570
4671 const char *pluginName = luaL_checkstring (luaVM, 1 );
4772 if (!pluginName || loadedPlugins.find (pluginName) != loadedPlugins.end () || !isSafePath (pluginName)) {
@@ -58,6 +83,7 @@ int CFunctions::amxLoadPlugin(lua_State *luaVM) {
5883 #endif
5984
6085 HMODULE hPlugin = loadLib (pluginPath.c_str ());
86+
6187 if (!hPlugin) {
6288 lua_pushboolean (luaVM, 0 );
6389 return 1 ;
@@ -77,10 +103,29 @@ int CFunctions::amxLoadPlugin(lua_State *luaVM) {
77103 }
78104
79105 printf (" Loading plugin %s\n " , pluginName);
80- Load_t *pfnLoad = (Load_t *)getProcAddr (hPlugin, " Load" );
106+
107+ Load_t* pfnLoad = (Load_t *)getProcAddr (hPlugin, " Load" );
108+ Supports_t* pfnSupports = (Supports_t *)getProcAddr (hPlugin, " Supports" );
109+
110+ SampPlugin* pSampPlugin = new SampPlugin;
111+ pSampPlugin->pPluginPointer = hPlugin;
112+ pSampPlugin->Unload = (Unload_t*)getProcAddr (hPlugin, " Unload" );
113+ pSampPlugin->dwSupportFlags = (SUPPORTS_FLAGS)pfnSupports ();
114+
115+ if ((pSampPlugin->dwSupportFlags & SUPPORTS_AMX_NATIVES) != 0 )
116+ {
117+ pSampPlugin->AmxLoad = (AmxLoad_t *)getProcAddr (hPlugin, " AmxLoad" );
118+ pSampPlugin->AmxUnload = (AmxUnload_t *)getProcAddr (hPlugin, " AmxUnload" );
119+ }
120+
121+ if ((pSampPlugin->dwSupportFlags & SUPPORTS_PROCESS_TICK) != 0 )
122+ {
123+ vecPfnProcessTick.push_back ((ProcessTick_t *)getProcAddr (hPlugin, " ProcessTick" ));
124+ }
125+
81126 pfnLoad (pluginInitData);
82127
83- loadedPlugins[pluginName] = hPlugin ;
128+ loadedPlugins[pluginName] = pSampPlugin ;
84129
85130 lua_pushboolean (luaVM, 1 );
86131 return 1 ;
@@ -127,9 +172,11 @@ int CFunctions::amxLoad(lua_State *luaVM) {
127172 amx_TimeInit (amx);
128173 amx_FileInit (amx);
129174 err = amx_SAMPInit (amx);
130- for (map< string, HMODULE >::iterator it = loadedPlugins.begin (); it != loadedPlugins.end (); it++) {
131- AmxLoad_t* pfnAmxLoad = (AmxLoad_t*)getProcAddr (it->second , " AmxLoad" );
132- err = pfnAmxLoad (amx);
175+ for (map< string, SampPlugin* >::iterator it = loadedPlugins.begin (); it != loadedPlugins.end (); it++) {
176+ AmxLoad_t* pfnAmxLoad = it->second ->AmxLoad ;
177+ if (pfnAmxLoad) {
178+ err = pfnAmxLoad (amx);
179+ }
133180 }
134181
135182 if (err != AMX_ERR_NONE) {
@@ -318,9 +365,11 @@ int CFunctions::amxUnload(lua_State *luaVM) {
318365 return 1 ;
319366 }
320367 // Call all plugins' AmxUnload function
321- for (map< string, HMODULE >::iterator piIt = loadedPlugins.begin (); piIt != loadedPlugins.end (); piIt++) {
322- AmxUnload_t *pfnAmxUnload = (AmxUnload_t*)getProcAddr (piIt->second , " AmxUnload" );
323- pfnAmxUnload (amx);
368+ for (map< string, SampPlugin* >::iterator piIt = loadedPlugins.begin (); piIt != loadedPlugins.end (); piIt++) {
369+ AmxUnload_t *pfnAmxUnload = piIt->second ->AmxUnload ;
370+ if (pfnAmxUnload) {
371+ pfnAmxUnload (amx);
372+ }
324373 }
325374 // Close any open databases
326375 if (loadedDBs.find (amx) != loadedDBs.end ()) {
@@ -341,9 +390,13 @@ int CFunctions::amxUnload(lua_State *luaVM) {
341390
342391// amxUnloadAllPlugins()
343392int CFunctions::amxUnloadAllPlugins (lua_State *luaVM) {
344- for (map< string, HMODULE >::iterator it = loadedPlugins.begin (); it != loadedPlugins.end (); it++)
345- freeLib (it->second );
393+ for (map< string, SampPlugin* >::iterator it = loadedPlugins.begin (); it != loadedPlugins.end (); it++) {
394+ it->second ->Unload ();
395+ freeLib (it->second ->pPluginPointer );
396+ delete it->second ;
397+ }
346398 loadedPlugins.clear ();
399+ vecPfnProcessTick.clear ();
347400
348401 lua_pushboolean (luaVM, 1 );
349402 return 1 ;
0 commit comments