void JPLua_Shutdown( void ) { if ( JPLua.state != NULL ) { jplua_plugin_t *nextPlugin = JPLua.plugins; JPLua_Event_Shutdown(); JPLua.currentPlugin = JPLua.plugins; while ( nextPlugin ) { luaL_unref( JPLua.state, LUA_REGISTRYINDEX, JPLua.currentPlugin->handle ); nextPlugin = JPLua.currentPlugin->next; free( JPLua.currentPlugin ); JPLua.currentPlugin = nextPlugin; } JPLua.plugins = JPLua.currentPlugin = NULL; lua_close( JPLua.state ); JPLua.state = NULL; } }
// initialise the JPLua system void JPLua_Init( void ) { #ifdef JPLUA size_t i = 0; #if defined(PROJECT_GAME) if ( !g_jplua.integer ) { #elif defined(PROJECT_CGAME) if ( !cg_jplua.integer ) { #endif return; } //Initialise and load base libraries memset( JPLua_Framework, -1, sizeof(JPLua_Framework) ); JPLua.state = luaL_newstate(); if ( !JPLua.state ) { //TODO: Fail gracefully return; } lua_atpanic( JPLua.state, JPLuaI_Error ); // Set the function called in a Lua error luaL_openlibs( JPLua.state ); luaopen_string( JPLua.state ); // Get rid of libraries we don't need lua_pushnil( JPLua.state ); lua_setglobal( JPLua.state, LUA_LOADLIBNAME ); // No need for the package library lua_pushnil( JPLua.state ); lua_setglobal( JPLua.state, LUA_IOLIBNAME ); // We use JKA engine facilities for file-handling // There are some stuff in the base library that we don't want lua_pushnil( JPLua.state ); lua_setglobal( JPLua.state, "dofile" ); lua_pushnil( JPLua.state ); lua_setglobal( JPLua.state, "loadfile" ); lua_pushnil( JPLua.state ); lua_setglobal( JPLua.state, "load" ); lua_pushnil( JPLua.state ); lua_setglobal( JPLua.state, "loadstring" ); // Some libraries we want, but not certain elements in them lua_getglobal( JPLua.state, LUA_OSLIBNAME ); // The OS library has dangerous access to the system, remove some parts of it lua_pushstring( JPLua.state, "execute" ); lua_pushnil( JPLua.state ); lua_settable( JPLua.state, -3 ); lua_pushstring( JPLua.state, "exit" ); lua_pushnil( JPLua.state ); lua_settable( JPLua.state, -3 ); lua_pushstring( JPLua.state, "remove" ); lua_pushnil( JPLua.state ); lua_settable( JPLua.state, -3 ); lua_pushstring( JPLua.state, "rename" ); lua_pushnil( JPLua.state ); lua_settable( JPLua.state, -3 ); lua_pushstring( JPLua.state, "setlocale" ); lua_pushnil( JPLua.state ); lua_settable( JPLua.state, -3 ); lua_pushstring( JPLua.state, "tmpname" ); lua_pushnil( JPLua.state ); lua_settable( JPLua.state, -3 ); lua_pop( JPLua.state, 1 ); // Redefine global functions lua_pushcclosure( JPLua.state, JPLua_Export_Print, 0 ); lua_setglobal( JPLua.state, "print" ); lua_pushcclosure( JPLua.state, JPLua_Export_Require, 0 ); lua_setglobal( JPLua.state, "require" ); for ( i = 0; i < cimportsSize; i++ ) lua_register( JPLua.state, JPLua_CImports[i].name, JPLua_CImports[i].function ); // Register our classes JPLua_Register_Player( JPLua.state ); JPLua_Register_Entity(JPLua.state); #ifdef PROJECT_CGAME JPLua_Register_Server( JPLua.state ); #endif JPLua_Register_Cvar( JPLua.state ); JPLua_Register_Logger( JPLua.state ); JPLua_Register_Serialiser( JPLua.state ); JPLua_Register_Vector( JPLua.state ); JPLua_Register_File( JPLua.state ); #ifdef PROJECT_GAME JPLua_Register_MySQL(JPLua.state); JPLua_Register_SQLite(JPLua.state); #endif // -- FRAMEWORK INITIALISATION begin lua_getglobal( JPLua.state, "tostring" ); JPLua_Framework[JPLUA_FRAMEWORK_TOSTRING] = luaL_ref( JPLua.state, LUA_REGISTRYINDEX ); lua_getglobal( JPLua.state, "pairs" ); JPLua_Framework[JPLUA_FRAMEWORK_PAIRS] = luaL_ref( JPLua.state, LUA_REGISTRYINDEX ); for ( i = 0; i < JPLUA_FRAMEWORK_MAX; i++ ) { if ( JPLua_Framework[i] < 0 ) Com_Error( ERR_FATAL, "FATAL ERROR: Could not properly initialize the JPLua framework!\n" ); } // -- FRAMEWORK INITIALISATION end //Call our base scripts JPLua_PostInit( JPLua.state ); #endif } void JPLua_Shutdown( void ) { #ifdef JPLUA if ( JPLua.state ) { jplua_plugin_t *nextPlugin = JPLua.plugins; JPLua_Event_Shutdown(); JPLua.currentPlugin = JPLua.plugins; while ( nextPlugin ) { for (int i = JPLUA_EVENT_UNLOAD; i < JPLUA_EVENT_MAX; i++){ if (JPLua.currentPlugin->eventListeners[i]) { luaL_unref(JPLua.state, LUA_REGISTRYINDEX, JPLua.currentPlugin->eventListeners[i]); } } luaL_unref( JPLua.state, LUA_REGISTRYINDEX, JPLua.currentPlugin->handle ); nextPlugin = JPLua.currentPlugin->next; free( JPLua.currentPlugin ); JPLua.currentPlugin = nextPlugin; } #ifdef PROJECT_GAME for (auto& row : jplua_client_commands){ luaL_unref(JPLua.state, LUA_REGISTRYINDEX, row.second); } jplua_client_commands.clear(); #elif defined PROJECT_CGAME for (auto& row : jplua_console_commands){ luaL_unref(JPLua.state, LUA_REGISTRYINDEX, row.second); } jplua_console_commands.clear(); #endif for (auto& row : jplua_server_commands){ luaL_unref(JPLua.state, LUA_REGISTRYINDEX, row.second); } jplua_server_commands.clear(); JPLua.plugins = JPLua.currentPlugin = NULL; lua_close( JPLua.state ); JPLua.state = NULL; JPLua.initialised = qfalse; } #endif }