diff --git a/src/script/cpp_api/s_async.cpp b/src/script/cpp_api/s_async.cpp index 93a200c22..5f1f9297e 100644 --- a/src/script/cpp_api/s_async.cpp +++ b/src/script/cpp_api/s_async.cpp @@ -198,6 +198,7 @@ void AsyncEngine::prepareEnvironment(lua_State* L, int top) AsyncWorkerThread::AsyncWorkerThread(AsyncEngine* jobDispatcher, const std::string &name) : Thread(name), + ScriptApiBase(ScriptingType::Async), jobDispatcher(jobDispatcher) { lua_State *L = getStack(); diff --git a/src/script/cpp_api/s_base.cpp b/src/script/cpp_api/s_base.cpp index c0d9a4f10..1decb836d 100644 --- a/src/script/cpp_api/s_base.cpp +++ b/src/script/cpp_api/s_base.cpp @@ -71,7 +71,8 @@ public: ScriptApiBase */ -ScriptApiBase::ScriptApiBase() +ScriptApiBase::ScriptApiBase(ScriptingType type): + m_type(type) { #ifdef SCRIPTAPI_LOCK_DEBUG m_lock_recursion_count = 0; @@ -82,7 +83,10 @@ ScriptApiBase::ScriptApiBase() lua_atpanic(m_luastack, &luaPanic); - luaL_openlibs(m_luastack); + if (m_type == ScriptingType::Client) + clientOpenLibs(m_luastack); + else + luaL_openlibs(m_luastack); // Make the ScriptApiBase* accessible to ModApiBase lua_pushlightuserdata(m_luastack, this); @@ -106,7 +110,10 @@ ScriptApiBase::ScriptApiBase() lua_newtable(m_luastack); lua_setglobal(m_luastack, "core"); - lua_pushstring(m_luastack, DIR_DELIM); + if (m_type == ScriptingType::Client) + lua_pushstring(m_luastack, "/"); + else + lua_pushstring(m_luastack, DIR_DELIM); lua_setglobal(m_luastack, "DIR_DELIM"); lua_pushstring(m_luastack, porting::getPlatformName()); @@ -128,6 +135,28 @@ int ScriptApiBase::luaPanic(lua_State *L) return 0; } +void ScriptApiBase::clientOpenLibs(lua_State *L) +{ + static const std::vector> m_libs = { + { "", luaopen_base }, + { LUA_LOADLIBNAME, luaopen_package }, + { LUA_TABLIBNAME, luaopen_table }, + { LUA_OSLIBNAME, luaopen_os }, + { LUA_STRLIBNAME, luaopen_string }, + { LUA_MATHLIBNAME, luaopen_math }, + { LUA_DBLIBNAME, luaopen_debug }, +#if USE_LUAJIT + { LUA_JITLIBNAME, luaopen_jit }, +#endif + }; + + for (const std::pair &lib : m_libs) { + lua_pushcfunction(L, lib.second); + lua_pushstring(L, lib.first.c_str()); + lua_call(L, 1, 0); + } +} + void ScriptApiBase::loadMod(const std::string &script_path, const std::string &mod_name) { diff --git a/src/script/cpp_api/s_base.h b/src/script/cpp_api/s_base.h index a170f82dc..18cb841cf 100644 --- a/src/script/cpp_api/s_base.h +++ b/src/script/cpp_api/s_base.h @@ -23,15 +23,19 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include #include +#include #include "util/basic_macros.h" extern "C" { #include +#include } #include "irrlichttypes.h" #include "common/c_types.h" #include "common/c_internal.h" +#include "debug.h" +#include "cmake_config.h" #define SCRIPTAPI_LOCK_DEBUG #define SCRIPTAPI_DEBUG @@ -54,9 +58,10 @@ extern "C" { setOriginFromTableRaw(index, __FUNCTION__) enum class ScriptingType: u8 { + Async, Client, - Server, - MainMenu + MainMenu, + Server }; class Server; @@ -70,7 +75,12 @@ class ServerActiveObject; class ScriptApiBase { public: - ScriptApiBase(); + ScriptApiBase(ScriptingType type); + // fake constructor to allow script API classes (e.g ScriptApiEnv) to virtually inherit from this one. + ScriptApiBase() + { + FATAL_ERROR("ScriptApiBase created without ScriptingType!"); + } virtual ~ScriptApiBase(); DISABLE_CLASS_COPY(ScriptApiBase); @@ -91,7 +101,6 @@ public: IGameDef *getGameDef() { return m_gamedef; } Server* getServer(); - void setType(ScriptingType type) { m_type = type; } ScriptingType getType() { return m_type; } #ifndef SERVER Client* getClient(); @@ -101,6 +110,8 @@ public: void setOriginDirect(const char *origin); void setOriginFromTableRaw(int index, const char *fxn); + void clientOpenLibs(lua_State *L); + protected: friend class LuaABM; friend class LuaLBM; diff --git a/src/script/scripting_client.cpp b/src/script/scripting_client.cpp index 29836c47b..14cdc199b 100644 --- a/src/script/scripting_client.cpp +++ b/src/script/scripting_client.cpp @@ -33,10 +33,10 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "lua_api/l_localplayer.h" #include "lua_api/l_camera.h" -ClientScripting::ClientScripting(Client *client) +ClientScripting::ClientScripting(Client *client): + ScriptApiBase(ScriptingType::Client) { setGameDef(client); - setType(ScriptingType::Client); SCRIPTAPI_PRECHECKHEADER @@ -59,9 +59,6 @@ ClientScripting::ClientScripting(Client *client) lua_pushstring(L, "client"); lua_setglobal(L, "INIT"); - lua_pushstring(L, "/"); - lua_setglobal(L, "DIR_DELIM"); - infostream << "SCRIPTAPI: Initialized client game modules" << std::endl; } diff --git a/src/script/scripting_mainmenu.cpp b/src/script/scripting_mainmenu.cpp index b8a44205a..0ff60951b 100644 --- a/src/script/scripting_mainmenu.cpp +++ b/src/script/scripting_mainmenu.cpp @@ -34,10 +34,10 @@ extern "C" { #define MAINMENU_NUM_ASYNC_THREADS 4 -MainMenuScripting::MainMenuScripting(GUIEngine* guiengine) +MainMenuScripting::MainMenuScripting(GUIEngine* guiengine): + ScriptApiBase(ScriptingType::MainMenu) { setGuiEngine(guiengine); - setType(ScriptingType::MainMenu); SCRIPTAPI_PRECHECKHEADER diff --git a/src/script/scripting_server.cpp b/src/script/scripting_server.cpp index 095216a74..1eee24c61 100644 --- a/src/script/scripting_server.cpp +++ b/src/script/scripting_server.cpp @@ -48,10 +48,10 @@ extern "C" { #include "lualib.h" } -ServerScripting::ServerScripting(Server* server) +ServerScripting::ServerScripting(Server* server): + ScriptApiBase(ScriptingType::Server) { setGameDef(server); - setType(ScriptingType::Server); // setEnv(env) is called by ScriptApiEnv::initializeEnvironment() // once the environment has been created