diff options
Diffstat (limited to 'src/script/cpp_api')
-rw-r--r-- | src/script/cpp_api/CMakeLists.txt | 10 | ||||
-rw-r--r-- | src/script/cpp_api/s_base.cpp | 279 | ||||
-rw-r--r-- | src/script/cpp_api/s_base.h | 119 | ||||
-rw-r--r-- | src/script/cpp_api/s_entity.cpp | 5 | ||||
-rw-r--r-- | src/script/cpp_api/s_env.cpp | 11 | ||||
-rw-r--r-- | src/script/cpp_api/s_internal.h | 63 | ||||
-rw-r--r-- | src/script/cpp_api/s_inventory.cpp | 1 | ||||
-rw-r--r-- | src/script/cpp_api/s_item.cpp | 3 | ||||
-rw-r--r-- | src/script/cpp_api/s_mainmenu.cpp | 80 | ||||
-rw-r--r-- | src/script/cpp_api/s_mainmenu.h | 49 | ||||
-rw-r--r-- | src/script/cpp_api/s_node.cpp | 2 | ||||
-rw-r--r-- | src/script/cpp_api/s_nodemeta.cpp | 6 | ||||
-rw-r--r-- | src/script/cpp_api/s_player.cpp | 15 | ||||
-rw-r--r-- | src/script/cpp_api/s_player.h | 2 | ||||
-rw-r--r-- | src/script/cpp_api/s_server.cpp | 151 | ||||
-rw-r--r-- | src/script/cpp_api/s_server.h (renamed from src/script/cpp_api/scriptapi.h) | 54 | ||||
-rw-r--r-- | src/script/cpp_api/scriptapi.cpp | 291 |
17 files changed, 556 insertions, 585 deletions
diff --git a/src/script/cpp_api/CMakeLists.txt b/src/script/cpp_api/CMakeLists.txt index 6f5b51a49..b753eda17 100644 --- a/src/script/cpp_api/CMakeLists.txt +++ b/src/script/cpp_api/CMakeLists.txt @@ -1,4 +1,5 @@ -set(SCRIPT_CPP_API_SRCS +# Used by server and client +set(common_SCRIPT_CPP_API_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/s_base.cpp ${CMAKE_CURRENT_SOURCE_DIR}/s_entity.cpp ${CMAKE_CURRENT_SOURCE_DIR}/s_env.cpp @@ -7,5 +8,10 @@ set(SCRIPT_CPP_API_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/s_node.cpp ${CMAKE_CURRENT_SOURCE_DIR}/s_nodemeta.cpp ${CMAKE_CURRENT_SOURCE_DIR}/s_player.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/scriptapi.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/s_server.cpp + PARENT_SCOPE) + +# Used by client only +set(minetest_SCRIPT_CPP_API_SRCS + ${CMAKE_CURRENT_SOURCE_DIR}/s_mainmenu.cpp PARENT_SCOPE) diff --git a/src/script/cpp_api/s_base.cpp b/src/script/cpp_api/s_base.cpp index e2e586357..e26d54ba7 100644 --- a/src/script/cpp_api/s_base.cpp +++ b/src/script/cpp_api/s_base.cpp @@ -17,30 +17,141 @@ with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#include "cpp_api/s_base.h" +#include "cpp_api/s_internal.h" +#include "lua_api/l_object.h" +#include "serverobject.h" +#include "debug.h" +#include "log.h" +#include "mods.h" +#include "util/string.h" + + +extern "C" { +#include "lualib.h" +} + #include <stdio.h> #include <cstdarg> -extern "C" { -#include "lua.h" -#include "lauxlib.h" + +class ModNameStorer +{ +private: + lua_State *L; +public: + ModNameStorer(lua_State *L_, const std::string modname): + L(L_) + { + // Store current modname in registry + lua_pushstring(L, modname.c_str()); + lua_setfield(L, LUA_REGISTRYINDEX, "minetest_current_modname"); + } + ~ModNameStorer() + { + // Clear current modname in registry + lua_pushnil(L); + lua_setfield(L, LUA_REGISTRYINDEX, "minetest_current_modname"); + } +}; + +static int loadScript_ErrorHandler(lua_State *L) { + lua_getfield(L, LUA_GLOBALSINDEX, "debug"); + if (!lua_istable(L, -1)) { + lua_pop(L, 1); + return 1; + } + lua_getfield(L, -1, "traceback"); + if (!lua_isfunction(L, -1)) { + lua_pop(L, 2); + return 1; + } + lua_pushvalue(L, 1); + lua_pushinteger(L, 2); + lua_call(L, 2, 1); + return 1; } -#include "cpp_api/s_base.h" -#include "lua_api/l_object.h" -#include "serverobject.h" -ScriptApiBase::ScriptApiBase() : - m_luastackmutex(), -#ifdef LOCK_DEBUG - m_locked(false), -#endif - m_luastack(0), - m_server(0), - m_environment(0) +/* + ScriptApiBase +*/ + +ScriptApiBase::ScriptApiBase() { + m_luastackmutex.Init(); + + #ifdef SCRIPTAPI_LOCK_DEBUG + m_locked = false; + #endif + m_luastack = luaL_newstate(); + assert(m_luastack); + + // Make the ScriptApiBase* accessible to ModApiBase + lua_pushlightuserdata(m_luastack, this); + lua_setfield(m_luastack, LUA_REGISTRYINDEX, "scriptapi"); + + m_server = 0; + m_environment = 0; + m_guiengine = 0; } +ScriptApiBase::~ScriptApiBase() +{ + lua_close(m_luastack); +} + +bool ScriptApiBase::loadMod(const std::string &scriptpath, + const std::string &modname) +{ + ModNameStorer modnamestorer(getStack(), modname); + + if(!string_allowed(modname, MODNAME_ALLOWED_CHARS)){ + errorstream<<"Error loading mod \""<<modname + <<"\": modname does not follow naming conventions: " + <<"Only chararacters [a-z0-9_] are allowed."<<std::endl; + return false; + } + + bool success = false; + + try{ + success = loadScript(scriptpath); + } + catch(LuaError &e){ + errorstream<<"Error loading mod \""<<modname + <<"\": "<<e.what()<<std::endl; + } + + return success; +} + +bool ScriptApiBase::loadScript(const std::string &scriptpath) +{ + verbosestream<<"Loading and running script from "<<scriptpath<<std::endl; + + lua_State *L = getStack(); + + lua_pushcfunction(L, loadScript_ErrorHandler); + int errorhandler = lua_gettop(L); + + int ret = luaL_loadfile(L, scriptpath.c_str()) || lua_pcall(L, 0, 0, errorhandler); + if(ret){ + errorstream<<"========== ERROR FROM LUA ==========="<<std::endl; + errorstream<<"Failed to load and run script from "<<std::endl; + errorstream<<scriptpath<<":"<<std::endl; + errorstream<<std::endl; + errorstream<<lua_tostring(L, -1)<<std::endl; + errorstream<<std::endl; + errorstream<<"=======END OF ERROR FROM LUA ========"<<std::endl; + lua_pop(L, 1); // Pop error message from stack + lua_pop(L, 1); // Pop the error handler from stack + return false; + } + lua_pop(L, 1); // Pop the error handler from stack + return true; +} void ScriptApiBase::realityCheck() { @@ -52,7 +163,7 @@ void ScriptApiBase::realityCheck() } } -void ScriptApiBase::scriptError(const char *fmt, ...) +void ScriptApiBase::scriptError(const char *fmt, ...) { va_list argp; va_start(argp, fmt); @@ -65,130 +176,34 @@ void ScriptApiBase::scriptError(const char *fmt, ...) void ScriptApiBase::stackDump(std::ostream &o) { - int i; - int top = lua_gettop(m_luastack); - for (i = 1; i <= top; i++) { /* repeat for each level */ - int t = lua_type(m_luastack, i); - switch (t) { - - case LUA_TSTRING: /* strings */ - o<<"\""<<lua_tostring(m_luastack, i)<<"\""; - break; - - case LUA_TBOOLEAN: /* booleans */ - o<<(lua_toboolean(m_luastack, i) ? "true" : "false"); - break; - - case LUA_TNUMBER: /* numbers */ { - char buf[10]; - snprintf(buf, 10, "%g", lua_tonumber(m_luastack, i)); - o<<buf; - break; } - - default: /* other values */ - o<<lua_typename(m_luastack, t); - break; - - } - o<<" "; - } - o<<std::endl; -} - -// Push the list of callbacks (a lua table). -// Then push nargs arguments. -// Then call this function, which -// - runs the callbacks -// - removes the table and arguments from the lua stack -// - pushes the return value, computed depending on mode -void ScriptApiBase::runCallbacks(int nargs,RunCallbacksMode mode) -{ - lua_State *L = getStack(); - - // Insert the return value into the lua stack, below the table - assert(lua_gettop(L) >= nargs + 1); - lua_pushnil(L); - lua_insert(L, -(nargs + 1) - 1); - // Stack now looks like this: - // ... <return value = nil> <table> <arg#1> <arg#2> ... <arg#n> + int i; + int top = lua_gettop(m_luastack); + for (i = 1; i <= top; i++) { /* repeat for each level */ + int t = lua_type(m_luastack, i); + switch (t) { - int rv = lua_gettop(L) - nargs - 1; - int table = rv + 1; - int arg = table + 1; + case LUA_TSTRING: /* strings */ + o<<"\""<<lua_tostring(m_luastack, i)<<"\""; + break; - luaL_checktype(L, table, LUA_TTABLE); + case LUA_TBOOLEAN: /* booleans */ + o<<(lua_toboolean(m_luastack, i) ? "true" : "false"); + break; - // Foreach - lua_pushnil(L); - bool first_loop = true; - while(lua_next(L, table) != 0){ - // key at index -2 and value at index -1 - luaL_checktype(L, -1, LUA_TFUNCTION); - // Call function - for(int i = 0; i < nargs; i++) - lua_pushvalue(L, arg+i); - if(lua_pcall(L, nargs, 1, 0)) - scriptError("error: %s", lua_tostring(L, -1)); - - // Move return value to designated space in stack - // Or pop it - if(first_loop){ - // Result of first callback is always moved - lua_replace(L, rv); - first_loop = false; - } else { - // Otherwise, what happens depends on the mode - if(mode == RUN_CALLBACKS_MODE_FIRST) - lua_pop(L, 1); - else if(mode == RUN_CALLBACKS_MODE_LAST) - lua_replace(L, rv); - else if(mode == RUN_CALLBACKS_MODE_AND || - mode == RUN_CALLBACKS_MODE_AND_SC){ - if((bool)lua_toboolean(L, rv) == true && - (bool)lua_toboolean(L, -1) == false) - lua_replace(L, rv); - else - lua_pop(L, 1); - } - else if(mode == RUN_CALLBACKS_MODE_OR || - mode == RUN_CALLBACKS_MODE_OR_SC){ - if((bool)lua_toboolean(L, rv) == false && - (bool)lua_toboolean(L, -1) == true) - lua_replace(L, rv); - else - lua_pop(L, 1); - } - else - assert(0); - } + case LUA_TNUMBER: /* numbers */ { + char buf[10]; + snprintf(buf, 10, "%g", lua_tonumber(m_luastack, i)); + o<<buf; + break; } - // Handle short circuit modes - if(mode == RUN_CALLBACKS_MODE_AND_SC && - (bool)lua_toboolean(L, rv) == false) - break; - else if(mode == RUN_CALLBACKS_MODE_OR_SC && - (bool)lua_toboolean(L, rv) == true) - break; + default: /* other values */ + o<<lua_typename(m_luastack, t); + break; - // value removed, keep key for next iteration - } - - // Remove stuff from stack, leaving only the return value - lua_settop(L, rv); - - // Fix return value in case no callbacks were called - if(first_loop){ - if(mode == RUN_CALLBACKS_MODE_AND || - mode == RUN_CALLBACKS_MODE_AND_SC){ - lua_pop(L, 1); - lua_pushboolean(L, true); - } - else if(mode == RUN_CALLBACKS_MODE_OR || - mode == RUN_CALLBACKS_MODE_OR_SC){ - lua_pop(L, 1); - lua_pushboolean(L, false); } + o<<" "; } + o<<std::endl; } void ScriptApiBase::addObjectReference(ServerActiveObject *cobj) diff --git a/src/script/cpp_api/s_base.h b/src/script/cpp_api/s_base.h index 8799d3c00..3cb59634b 100644 --- a/src/script/cpp_api/s_base.h +++ b/src/script/cpp_api/s_base.h @@ -21,67 +21,37 @@ with this program; if not, write to the Free Software Foundation, Inc., #define S_BASE_H_ #include <iostream> +#include <string> + +extern "C" { +#include <lua.h> +} #include "irrlichttypes.h" #include "jmutex.h" #include "jmutexautolock.h" #include "common/c_types.h" -#include "debug.h" -#define LOCK_DEBUG +#define SCRIPTAPI_LOCK_DEBUG class Server; class Environment; +class GUIEngine; class ServerActiveObject; -class LuaABM; -class InvRef; -class ModApiBase; -class ModApiEnvMod; -class ObjectRef; -class NodeMetaRef; - - -/* definitions */ -// What scriptapi_run_callbacks does with the return values of callbacks. -// Regardless of the mode, if only one callback is defined, -// its return value is the total return value. -// Modes only affect the case where 0 or >= 2 callbacks are defined. -enum RunCallbacksMode -{ - // Returns the return value of the first callback - // Returns nil if list of callbacks is empty - RUN_CALLBACKS_MODE_FIRST, - // Returns the return value of the last callback - // Returns nil if list of callbacks is empty - RUN_CALLBACKS_MODE_LAST, - // If any callback returns a false value, the first such is returned - // Otherwise, the first callback's return value (trueish) is returned - // Returns true if list of callbacks is empty - RUN_CALLBACKS_MODE_AND, - // Like above, but stops calling callbacks (short circuit) - // after seeing the first false value - RUN_CALLBACKS_MODE_AND_SC, - // If any callback returns a true value, the first such is returned - // Otherwise, the first callback's return value (falseish) is returned - // Returns false if list of callbacks is empty - RUN_CALLBACKS_MODE_OR, - // Like above, but stops calling callbacks (short circuit) - // after seeing the first true value - RUN_CALLBACKS_MODE_OR_SC, - // Note: "a true value" and "a false value" refer to values that - // are converted by lua_toboolean to true or false, respectively. -}; - class ScriptApiBase { public: + ScriptApiBase(); + virtual ~ScriptApiBase(); + + bool loadMod(const std::string &scriptpath, const std::string &modname); + bool loadScript(const std::string &scriptpath); + /* object */ void addObjectReference(ServerActiveObject *cobj); void removeObjectReference(ServerActiveObject *cobj); - ScriptApiBase(); - protected: friend class LuaABM; friend class InvRef; @@ -91,78 +61,35 @@ protected: friend class ModApiEnvMod; friend class LuaVoxelManip; - - inline lua_State* getStack() + lua_State* getStack() { return m_luastack; } - bool setStack(lua_State* stack) { - if (m_luastack == 0) { - m_luastack = stack; - return true; - } - return false; - } - void realityCheck(); void scriptError(const char *fmt, ...); void stackDump(std::ostream &o); - void runCallbacks(int nargs,RunCallbacksMode mode); - inline Server* getServer() { return m_server; } + Server* getServer() { return m_server; } void setServer(Server* server) { m_server = server; } Environment* getEnv() { return m_environment; } void setEnv(Environment* env) { m_environment = env; } + GUIEngine* getGuiEngine() { return m_guiengine; } + void setGuiEngine(GUIEngine* guiengine) { m_guiengine = guiengine; } + void objectrefGetOrCreate(ServerActiveObject *cobj); void objectrefGet(u16 id); - JMutex m_luastackmutex; -#ifdef LOCK_DEBUG + JMutex m_luastackmutex; +#ifdef SCRIPTAPI_LOCK_DEBUG bool m_locked; #endif private: lua_State* m_luastack; - Server* m_server; - Environment* m_environment; - - -}; - -#ifdef LOCK_DEBUG -class LockChecker { -public: - LockChecker(bool* variable) { - assert(*variable == false); - - m_variable = variable; - *m_variable = true; - } - ~LockChecker() { - *m_variable = false; - } -private: -bool* m_variable; + Server* m_server; + Environment* m_environment; + GUIEngine* m_guiengine; }; -#define LOCK_CHECK LockChecker(&(this->m_locked)) -#else -#define LOCK_CHECK while(0) -#endif - -#define LUA_STACK_AUTOLOCK JMutexAutoLock(this->m_luastackmutex) - -#define SCRIPTAPI_PRECHECKHEADER \ - LUA_STACK_AUTOLOCK; \ - LOCK_CHECK; \ - realityCheck(); \ - lua_State *L = getStack(); \ - assert(lua_checkstack(L, 20)); \ - StackUnroller stack_unroller(L); - -#define PLAYER_TO_SA(p) p->getEnv()->getScriptIface() -#define ENV_TO_SA(env) env->getScriptIface() -#define SERVER_TO_SA(srv) srv->getScriptIface() - #endif /* S_BASE_H_ */ diff --git a/src/script/cpp_api/s_entity.cpp b/src/script/cpp_api/s_entity.cpp index c494e8232..cefa27cb1 100644 --- a/src/script/cpp_api/s_entity.cpp +++ b/src/script/cpp_api/s_entity.cpp @@ -18,15 +18,12 @@ with this program; if not, write to the Free Software Foundation, Inc., */ #include "cpp_api/s_entity.h" +#include "cpp_api/s_internal.h" #include "log.h" #include "object_properties.h" #include "common/c_converter.h" #include "common/c_content.h" -extern "C" { -#include "lauxlib.h" -} - bool ScriptApiEntity::luaentity_Add(u16 id, const char *name) { SCRIPTAPI_PRECHECKHEADER diff --git a/src/script/cpp_api/s_env.cpp b/src/script/cpp_api/s_env.cpp index 632b28f45..ef3a1dddf 100644 --- a/src/script/cpp_api/s_env.cpp +++ b/src/script/cpp_api/s_env.cpp @@ -18,16 +18,13 @@ with this program; if not, write to the Free Software Foundation, Inc., */ #include "cpp_api/s_env.h" +#include "cpp_api/s_internal.h" #include "common/c_converter.h" #include "log.h" #include "environment.h" #include "mapgen.h" #include "lua_api/l_env.h" -extern "C" { -#include "lauxlib.h" -} - void ScriptApiEnv::environment_OnGenerated(v3s16 minp, v3s16 maxp, u32 blockseed) { @@ -40,7 +37,7 @@ void ScriptApiEnv::environment_OnGenerated(v3s16 minp, v3s16 maxp, push_v3s16(L, minp); push_v3s16(L, maxp); lua_pushnumber(L, blockseed); - runCallbacks(3, RUN_CALLBACKS_MODE_FIRST); + script_run_callbacks(L, 3, RUN_CALLBACKS_MODE_FIRST); } void ScriptApiEnv::environment_Step(float dtime) @@ -53,7 +50,7 @@ void ScriptApiEnv::environment_Step(float dtime) lua_getfield(L, -1, "registered_globalsteps"); // Call callbacks lua_pushnumber(L, dtime); - runCallbacks(1, RUN_CALLBACKS_MODE_FIRST); + script_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST); } void ScriptApiEnv::environment_OnMapgenInit(MapgenParams *mgparams) @@ -80,7 +77,7 @@ void ScriptApiEnv::environment_OnMapgenInit(MapgenParams *mgparams) lua_pushstring(L, flagstr.c_str()); lua_setfield(L, -2, "flags"); - runCallbacks(1, RUN_CALLBACKS_MODE_FIRST); + script_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST); } void ScriptApiEnv::initializeEnvironment(ServerEnvironment *env) diff --git a/src/script/cpp_api/s_internal.h b/src/script/cpp_api/s_internal.h new file mode 100644 index 000000000..10ee1a7de --- /dev/null +++ b/src/script/cpp_api/s_internal.h @@ -0,0 +1,63 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com> + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +/******************************************************************************/ +/******************************************************************************/ +/* WARNING!!!! do NOT add this header in any include file or any code file */ +/* not being a modapi file!!!!!!!! */ +/******************************************************************************/ +/******************************************************************************/ + +#ifndef S_INTERNAL_H_ +#define S_INTERNAL_H_ + +#include "common/c_internal.h" +#include "cpp_api/s_base.h" + +#ifdef SCRIPTAPI_LOCK_DEBUG +#include "debug.h" // assert() +class LockChecker { +public: + LockChecker(bool* variable) { + assert(*variable == false); + + m_variable = variable; + *m_variable = true; + } + ~LockChecker() { + *m_variable = false; + } +private: +bool* m_variable; +}; + +#define SCRIPTAPI_LOCK_CHECK LockChecker(&(this->m_locked)) +#else +#define SCRIPTAPI_LOCK_CHECK while(0) +#endif + +#define SCRIPTAPI_PRECHECKHEADER \ + JMutexAutoLock(this->m_luastackmutex); \ + SCRIPTAPI_LOCK_CHECK; \ + realityCheck(); \ + lua_State *L = getStack(); \ + assert(lua_checkstack(L, 20)); \ + StackUnroller stack_unroller(L); + +#endif /* S_INTERNAL_H_ */ diff --git a/src/script/cpp_api/s_inventory.cpp b/src/script/cpp_api/s_inventory.cpp index 2402d198c..09f26d80c 100644 --- a/src/script/cpp_api/s_inventory.cpp +++ b/src/script/cpp_api/s_inventory.cpp @@ -18,6 +18,7 @@ with this program; if not, write to the Free Software Foundation, Inc., */ #include "cpp_api/s_inventory.h" +#include "cpp_api/s_internal.h" #include "inventorymanager.h" #include "lua_api/l_inventory.h" #include "lua_api/l_item.h" diff --git a/src/script/cpp_api/s_item.cpp b/src/script/cpp_api/s_item.cpp index 6937ebbeb..b4536ac63 100644 --- a/src/script/cpp_api/s_item.cpp +++ b/src/script/cpp_api/s_item.cpp @@ -18,10 +18,13 @@ with this program; if not, write to the Free Software Foundation, Inc., */ #include "cpp_api/s_item.h" +#include "cpp_api/s_internal.h" #include "common/c_converter.h" #include "common/c_content.h" #include "lua_api/l_item.h" #include "server.h" +#include "log.h" +#include "util/pointedthing.h" bool ScriptApiItem::item_OnDrop(ItemStack &item, ServerActiveObject *dropper, v3f pos) diff --git a/src/script/cpp_api/s_mainmenu.cpp b/src/script/cpp_api/s_mainmenu.cpp new file mode 100644 index 000000000..af92c59a9 --- /dev/null +++ b/src/script/cpp_api/s_mainmenu.cpp @@ -0,0 +1,80 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com> + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "cpp_api/s_mainmenu.h" +#include "cpp_api/s_internal.h" +#include "common/c_converter.h" + +void ScriptApiMainMenu::setMainMenuErrorMessage(std::string errormessage) +{ + SCRIPTAPI_PRECHECKHEADER + + lua_getglobal(L, "gamedata"); + int gamedata_idx = lua_gettop(L); + lua_pushstring(L, "errormessage"); + lua_pushstring(L, errormessage.c_str()); + lua_settable(L, gamedata_idx); + lua_pop(L, 1); +} + +void ScriptApiMainMenu::handleMainMenuEvent(std::string text) +{ + SCRIPTAPI_PRECHECKHEADER + + // Get handler function + lua_getglobal(L, "engine"); + lua_getfield(L, -1, "event_handler"); + if(lua_isnil(L, -1)) + return; + luaL_checktype(L, -1, LUA_TFUNCTION); + + // Call it + lua_pushstring(L, text.c_str()); + if(lua_pcall(L, 1, 0, 0)) + scriptError("error running function engine.event_handler: %s\n", + lua_tostring(L, -1)); +} + +void ScriptApiMainMenu::handleMainMenuButtons(std::map<std::string, std::string> fields) +{ + SCRIPTAPI_PRECHECKHEADER + + // Get handler function + lua_getglobal(L, "engine"); + lua_getfield(L, -1, "button_handler"); + if(lua_isnil(L, -1)) + return; + luaL_checktype(L, -1, LUA_TFUNCTION); + + // Convert fields to lua table + lua_newtable(L); + for(std::map<std::string, std::string>::const_iterator + i = fields.begin(); i != fields.end(); i++){ + const std::string &name = i->first; + const std::string &value = i->second; + lua_pushstring(L, name.c_str()); + lua_pushlstring(L, value.c_str(), value.size()); + lua_settable(L, -3); + } + + // Call it + if(lua_pcall(L, 1, 0, 0)) + scriptError("error running function engine.button_handler: %s\n", + lua_tostring(L, -1)); +} diff --git a/src/script/cpp_api/s_mainmenu.h b/src/script/cpp_api/s_mainmenu.h new file mode 100644 index 000000000..53dcd37e9 --- /dev/null +++ b/src/script/cpp_api/s_mainmenu.h @@ -0,0 +1,49 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com> + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef S_MAINMENU_H_ +#define S_MAINMENU_H_ + +#include "cpp_api/s_base.h" +#include <map> + +class ScriptApiMainMenu + : virtual public ScriptApiBase +{ +public: + /** + * set gamedata.errormessage to inform lua of an error + * @param errormessage the error message + */ + void setMainMenuErrorMessage(std::string errormessage); + + /** + * process events received from formspec + * @param text events in textual form + */ + void handleMainMenuEvent(std::string text); + + /** + * process field data recieved from formspec + * @param fields data in field format + */ + void handleMainMenuButtons(std::map<std::string, std::string> fields); +}; + +#endif /* S_MAINMENU_H_ */ diff --git a/src/script/cpp_api/s_node.cpp b/src/script/cpp_api/s_node.cpp index d0b0583c0..92fd00a74 100644 --- a/src/script/cpp_api/s_node.cpp +++ b/src/script/cpp_api/s_node.cpp @@ -18,10 +18,12 @@ with this program; if not, write to the Free Software Foundation, Inc., */ #include "cpp_api/s_node.h" +#include "cpp_api/s_internal.h" #include "common/c_converter.h" #include "common/c_content.h" #include "nodedef.h" #include "server.h" +#include "environment.h" struct EnumString ScriptApiNode::es_DrawType[] = diff --git a/src/script/cpp_api/s_nodemeta.cpp b/src/script/cpp_api/s_nodemeta.cpp index 56cea8e5f..e87464c61 100644 --- a/src/script/cpp_api/s_nodemeta.cpp +++ b/src/script/cpp_api/s_nodemeta.cpp @@ -18,16 +18,14 @@ with this program; if not, write to the Free Software Foundation, Inc., */ #include "cpp_api/s_nodemeta.h" +#include "cpp_api/s_internal.h" #include "common/c_converter.h" #include "nodedef.h" #include "mapnode.h" #include "server.h" +#include "environment.h" #include "lua_api/l_item.h" -extern "C" { -#include "lauxlib.h" -} - // Return number of accepted items to be moved int ScriptApiNodemeta::nodemeta_inventory_AllowMove(v3s16 p, const std::string &from_list, int from_index, diff --git a/src/script/cpp_api/s_player.cpp b/src/script/cpp_api/s_player.cpp index 0dbd52527..215a34d53 100644 --- a/src/script/cpp_api/s_player.cpp +++ b/src/script/cpp_api/s_player.cpp @@ -18,6 +18,7 @@ with this program; if not, write to the Free Software Foundation, Inc., */ #include "cpp_api/s_player.h" +#include "cpp_api/s_internal.h" void ScriptApiPlayer::on_newplayer(ServerActiveObject *player) { @@ -28,7 +29,7 @@ void ScriptApiPlayer::on_newplayer(ServerActiveObject *player) lua_getfield(L, -1, "registered_on_newplayers"); // Call callbacks objectrefGetOrCreate(player); - runCallbacks(1, RUN_CALLBACKS_MODE_FIRST); + script_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST); } void ScriptApiPlayer::on_dieplayer(ServerActiveObject *player) @@ -40,7 +41,7 @@ void ScriptApiPlayer::on_dieplayer(ServerActiveObject *player) lua_getfield(L, -1, "registered_on_dieplayers"); // Call callbacks objectrefGetOrCreate(player); - runCallbacks(1, RUN_CALLBACKS_MODE_FIRST); + script_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST); } bool ScriptApiPlayer::on_respawnplayer(ServerActiveObject *player) @@ -52,7 +53,7 @@ bool ScriptApiPlayer::on_respawnplayer(ServerActiveObject *player) lua_getfield(L, -1, "registered_on_respawnplayers"); // Call callbacks objectrefGetOrCreate(player); - runCallbacks(1, RUN_CALLBACKS_MODE_OR); + script_run_callbacks(L, 1, RUN_CALLBACKS_MODE_OR); bool positioning_handled_by_some = lua_toboolean(L, -1); return positioning_handled_by_some; } @@ -66,7 +67,7 @@ void ScriptApiPlayer::on_joinplayer(ServerActiveObject *player) lua_getfield(L, -1, "registered_on_joinplayers"); // Call callbacks objectrefGetOrCreate(player); - runCallbacks(1, RUN_CALLBACKS_MODE_FIRST); + script_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST); } void ScriptApiPlayer::on_leaveplayer(ServerActiveObject *player) @@ -78,7 +79,7 @@ void ScriptApiPlayer::on_leaveplayer(ServerActiveObject *player) lua_getfield(L, -1, "registered_on_leaveplayers"); // Call callbacks objectrefGetOrCreate(player); - runCallbacks(1, RUN_CALLBACKS_MODE_FIRST); + script_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST); } void ScriptApiPlayer::on_cheat(ServerActiveObject *player, @@ -94,7 +95,7 @@ void ScriptApiPlayer::on_cheat(ServerActiveObject *player, lua_newtable(L); lua_pushlstring(L, cheat_type.c_str(), cheat_type.size()); lua_setfield(L, -2, "type"); - runCallbacks(2, RUN_CALLBACKS_MODE_FIRST); + script_run_callbacks(L, 2, RUN_CALLBACKS_MODE_FIRST); } void ScriptApiPlayer::on_playerReceiveFields(ServerActiveObject *player, @@ -121,7 +122,7 @@ void ScriptApiPlayer::on_playerReceiveFields(ServerActiveObject *player, lua_pushlstring(L, value.c_str(), value.size()); lua_settable(L, -3); } - runCallbacks(3, RUN_CALLBACKS_MODE_OR_SC); + script_run_callbacks(L, 3, RUN_CALLBACKS_MODE_OR_SC); } ScriptApiPlayer::~ScriptApiPlayer() { } diff --git a/src/script/cpp_api/s_player.h b/src/script/cpp_api/s_player.h index c0409a481..88221f486 100644 --- a/src/script/cpp_api/s_player.h +++ b/src/script/cpp_api/s_player.h @@ -20,6 +20,8 @@ with this program; if not, write to the Free Software Foundation, Inc., #ifndef S_PLAYER_H_ #define S_PLAYER_H_ +#include <map> + #include "cpp_api/s_base.h" diff --git a/src/script/cpp_api/s_server.cpp b/src/script/cpp_api/s_server.cpp new file mode 100644 index 000000000..d41805b7b --- /dev/null +++ b/src/script/cpp_api/s_server.cpp @@ -0,0 +1,151 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com> + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "cpp_api/s_server.h" +#include "cpp_api/s_internal.h" +#include "common/c_converter.h" + +bool ScriptApiServer::getAuth(const std::string &playername, + std::string *dst_password, + std::set<std::string> *dst_privs) +{ + SCRIPTAPI_PRECHECKHEADER + + getAuthHandler(); + lua_getfield(L, -1, "get_auth"); + if(lua_type(L, -1) != LUA_TFUNCTION) + throw LuaError(L, "Authentication handler missing get_auth"); + lua_pushstring(L, playername.c_str()); + if(lua_pcall(L, 1, 1, 0)) + scriptError("error: %s", lua_tostring(L, -1)); + + // nil = login not allowed + if(lua_isnil(L, -1)) + return false; + luaL_checktype(L, -1, LUA_TTABLE); + + std::string password; + bool found = getstringfield(L, -1, "password", password); + if(!found) + throw LuaError(L, "Authentication handler didn't return password"); + if(dst_password) + *dst_password = password; + + lua_getfield(L, -1, "privileges"); + if(!lua_istable(L, -1)) + throw LuaError(L, + "Authentication handler didn't return privilege table"); + if(dst_privs) + readPrivileges(-1, *dst_privs); + lua_pop(L, 1); + + return true; +} + +void ScriptApiServer::getAuthHandler() +{ + lua_State *L = getStack(); + + lua_getglobal(L, "minetest"); + lua_getfield(L, -1, "registered_auth_handler"); + if(lua_isnil(L, -1)){ + lua_pop(L, 1); + lua_getfield(L, -1, "builtin_auth_handler"); + } + if(lua_type(L, -1) != LUA_TTABLE) + throw LuaError(L, "Authentication handler table not valid"); +} + +void ScriptApiServer::readPrivileges(int index, std::set<std::string> &result) +{ + lua_State *L = getStack(); + + result.clear(); + lua_pushnil(L); + if(index < 0) + index -= 1; + while(lua_next(L, index) != 0){ + // key at index -2 and value at index -1 + std::string key = luaL_checkstring(L, -2); + bool value = lua_toboolean(L, -1); + if(value) + result.insert(key); + // removes value, keeps key for next iteration + lua_pop(L, 1); + } +} + +void ScriptApiServer::createAuth(const std::string &playername, + const std::string &password) +{ + SCRIPTAPI_PRECHECKHEADER + + getAuthHandler(); + lua_getfield(L, -1, "create_auth"); + if(lua_type(L, -1) != LUA_TFUNCTION) + throw LuaError(L, "Authentication handler missing create_auth"); + lua_pushstring(L, playername.c_str()); + lua_pushstring(L, password.c_str()); + if(lua_pcall(L, 2, 0, 0)) + scriptError("error: %s", lua_tostring(L, -1)); +} + +bool ScriptApiServer::setPassword(const std::string &playername, + const std::string &password) +{ + SCRIPTAPI_PRECHECKHEADER + + getAuthHandler(); + lua_getfield(L, -1, "set_password"); + if(lua_type(L, -1) != LUA_TFUNCTION) + throw LuaError(L, "Authentication handler missing set_password"); + lua_pushstring(L, playername.c_str()); + lua_pushstring(L, password.c_str()); + if(lua_pcall(L, 2, 1, 0)) + scriptError("error: %s", lua_tostring(L, -1)); + return lua_toboolean(L, -1); +} + +bool ScriptApiServer::on_chat_message(const std::string &name, + const std::string &message) +{ + SCRIPTAPI_PRECHECKHEADER + + // Get minetest.registered_on_chat_messages + lua_getglobal(L, "minetest"); + lua_getfield(L, -1, "registered_on_chat_messages"); + // Call callbacks + lua_pushstring(L, name.c_str()); + lua_pushstring(L, message.c_str()); + script_run_callbacks(L, 2, RUN_CALLBACKS_MODE_OR_SC); + bool ate = lua_toboolean(L, -1); + return ate; +} + +void ScriptApiServer::on_shutdown() +{ + SCRIPTAPI_PRECHECKHEADER + + // Get registered shutdown hooks + lua_getglobal(L, "minetest"); + lua_getfield(L, -1, "registered_on_shutdown"); + // Call callbacks + script_run_callbacks(L, 0, RUN_CALLBACKS_MODE_FIRST); +} + diff --git a/src/script/cpp_api/scriptapi.h b/src/script/cpp_api/s_server.h index bbd0bdda7..a63e36320 100644 --- a/src/script/cpp_api/scriptapi.h +++ b/src/script/cpp_api/s_server.h @@ -17,66 +17,36 @@ with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef SCRIPTAPI_H_ -#define SCRIPTAPI_H_ - -#include <map> -#include <set> -#include <vector> +#ifndef S_SERVER_H_ +#define S_SERVER_H_ #include "cpp_api/s_base.h" -#include "cpp_api/s_player.h" -#include "cpp_api/s_env.h" -#include "cpp_api/s_node.h" -#include "cpp_api/s_inventory.h" -#include "cpp_api/s_entity.h" - -class ModApiBase; - -/*****************************************************************************/ -/* Scriptapi <-> Core Interface */ -/*****************************************************************************/ +#include <set> -class ScriptApi - : virtual public ScriptApiBase, - public ScriptApiPlayer, - public ScriptApiEnv, - public ScriptApiNode, - public ScriptApiDetached, - public ScriptApiEntity +class ScriptApiServer + : virtual public ScriptApiBase { public: - ScriptApi(); - ScriptApi(Server* server); - ~ScriptApi(); - + // Calls on_chat_message handlers // Returns true if script handled message bool on_chat_message(const std::string &name, const std::string &message); - /* server */ + // Calls on_shutdown handlers void on_shutdown(); /* auth */ bool getAuth(const std::string &playername, - std::string *dst_password, std::set<std::string> *dst_privs); + std::string *dst_password, + std::set<std::string> *dst_privs); void createAuth(const std::string &playername, const std::string &password); bool setPassword(const std::string &playername, const std::string &password); - - /** register a lua api module to scriptapi */ - static bool registerModApiModule(ModApiBase* prototype); - /** load a mod **/ - bool loadMod(const std::string &scriptpath,const std::string &modname); - private: void getAuthHandler(); - void readPrivileges(int index,std::set<std::string> &result); - - bool scriptLoad(const char *path); + void readPrivileges(int index, std::set<std::string> &result); +}; - static std::vector<ModApiBase*>* m_mod_api_modules; -}; -#endif /* SCRIPTAPI_H_ */ +#endif /* S_SERVER_H_ */ diff --git a/src/script/cpp_api/scriptapi.cpp b/src/script/cpp_api/scriptapi.cpp deleted file mode 100644 index b6d376b1f..000000000 --- a/src/script/cpp_api/scriptapi.cpp +++ /dev/null @@ -1,291 +0,0 @@ -/* -Minetest -Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com> - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation; either version 2.1 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License along -with this program; if not, write to the Free Software Foundation, Inc., -51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -extern "C" { -#include "lua.h" -#include "lauxlib.h" -#include "lualib.h" -} - - -#include "scriptapi.h" -#include "common/c_converter.h" -#include "lua_api/l_base.h" -#include "log.h" -#include "mods.h" - -int script_ErrorHandler(lua_State *L) { - lua_getfield(L, LUA_GLOBALSINDEX, "debug"); - if (!lua_istable(L, -1)) { - lua_pop(L, 1); - return 1; - } - lua_getfield(L, -1, "traceback"); - if (!lua_isfunction(L, -1)) { - lua_pop(L, 2); - return 1; - } - lua_pushvalue(L, 1); - lua_pushinteger(L, 2); - lua_call(L, 2, 1); - return 1; -} - - -bool ScriptApi::getAuth(const std::string &playername, - std::string *dst_password, std::set<std::string> *dst_privs) -{ - SCRIPTAPI_PRECHECKHEADER - - getAuthHandler(); - lua_getfield(L, -1, "get_auth"); - if(lua_type(L, -1) != LUA_TFUNCTION) - throw LuaError(L, "Authentication handler missing get_auth"); - lua_pushstring(L, playername.c_str()); - if(lua_pcall(L, 1, 1, 0)) - scriptError("error: %s", lua_tostring(L, -1)); - - // nil = login not allowed - if(lua_isnil(L, -1)) - return false; - luaL_checktype(L, -1, LUA_TTABLE); - - std::string password; - bool found = getstringfield(L, -1, "password", password); - if(!found) - throw LuaError(L, "Authentication handler didn't return password"); - if(dst_password) - *dst_password = password; - - lua_getfield(L, -1, "privileges"); - if(!lua_istable(L, -1)) - throw LuaError(L, - "Authentication handler didn't return privilege table"); - if(dst_privs) - readPrivileges(-1, *dst_privs); - lua_pop(L, 1); - - return true; -} - -void ScriptApi::getAuthHandler() -{ - lua_State *L = getStack(); - - lua_getglobal(L, "minetest"); - lua_getfield(L, -1, "registered_auth_handler"); - if(lua_isnil(L, -1)){ - lua_pop(L, 1); - lua_getfield(L, -1, "builtin_auth_handler"); - } - if(lua_type(L, -1) != LUA_TTABLE) - throw LuaError(L, "Authentication handler table not valid"); -} - -void ScriptApi::readPrivileges(int index,std::set<std::string> &result) -{ - lua_State *L = getStack(); - - result.clear(); - lua_pushnil(L); - if(index < 0) - index -= 1; - while(lua_next(L, index) != 0){ - // key at index -2 and value at index -1 - std::string key = luaL_checkstring(L, -2); - bool value = lua_toboolean(L, -1); - if(value) - result.insert(key); - // removes value, keeps key for next iteration - lua_pop(L, 1); - } -} - -void ScriptApi::createAuth(const std::string &playername, - const std::string &password) -{ - SCRIPTAPI_PRECHECKHEADER - - getAuthHandler(); - lua_getfield(L, -1, "create_auth"); - if(lua_type(L, -1) != LUA_TFUNCTION) - throw LuaError(L, "Authentication handler missing create_auth"); - lua_pushstring(L, playername.c_str()); - lua_pushstring(L, password.c_str()); - if(lua_pcall(L, 2, 0, 0)) - scriptError("error: %s", lua_tostring(L, -1)); -} - -bool ScriptApi::setPassword(const std::string &playername, - const std::string &password) -{ - SCRIPTAPI_PRECHECKHEADER - - getAuthHandler(); - lua_getfield(L, -1, "set_password"); - if(lua_type(L, -1) != LUA_TFUNCTION) - throw LuaError(L, "Authentication handler missing set_password"); - lua_pushstring(L, playername.c_str()); - lua_pushstring(L, password.c_str()); - if(lua_pcall(L, 2, 1, 0)) - scriptError("error: %s", lua_tostring(L, -1)); - return lua_toboolean(L, -1); -} - -bool ScriptApi::on_chat_message(const std::string &name, - const std::string &message) -{ - SCRIPTAPI_PRECHECKHEADER - - // Get minetest.registered_on_chat_messages - lua_getglobal(L, "minetest"); - lua_getfield(L, -1, "registered_on_chat_messages"); - // Call callbacks - lua_pushstring(L, name.c_str()); - lua_pushstring(L, message.c_str()); - runCallbacks(2, RUN_CALLBACKS_MODE_OR_SC); - bool ate = lua_toboolean(L, -1); - return ate; -} - -void ScriptApi::on_shutdown() -{ - SCRIPTAPI_PRECHECKHEADER - - // Get registered shutdown hooks - lua_getglobal(L, "minetest"); - lua_getfield(L, -1, "registered_on_shutdown"); - // Call callbacks - runCallbacks(0, RUN_CALLBACKS_MODE_FIRST); -} - -bool ScriptApi::loadMod(const std::string &scriptpath,const std::string &modname) -{ - ModNameStorer modnamestorer(getStack(), modname); - - if(!string_allowed(modname, MODNAME_ALLOWED_CHARS)){ - errorstream<<"Error loading mod \""<<modname - <<"\": modname does not follow naming conventions: " - <<"Only chararacters [a-z0-9_] are allowed."<<std::endl; - return false; - } - - bool success = false; - - try{ - success = scriptLoad(scriptpath.c_str()); - } - catch(LuaError &e){ - errorstream<<"Error loading mod \""<<modname - <<"\": "<<e.what()<<std::endl; - } - - return success; -} - -ScriptApi::ScriptApi() { - assert("Invalid call to default constructor of scriptapi!" == 0); -} - -ScriptApi::ScriptApi(Server* server) -{ - - setServer(server); - setStack(luaL_newstate()); - assert(getStack()); - - //TODO add security - - luaL_openlibs(getStack()); - - SCRIPTAPI_PRECHECKHEADER - - lua_pushlightuserdata(L, this); - lua_setfield(L, LUA_REGISTRYINDEX, "scriptapi"); - - lua_newtable(L); - lua_setglobal(L, "minetest"); - - - for (std::vector<ModApiBase*>::iterator i = m_mod_api_modules->begin(); - i != m_mod_api_modules->end(); i++) { - //initializers are called within minetest global table! - lua_getglobal(L, "minetest"); - int top = lua_gettop(L); - bool ModInitializedSuccessfull = (*i)->Initialize(L,top); - assert(ModInitializedSuccessfull); - } - - infostream << "SCRIPTAPI: initialized " << m_mod_api_modules->size() - << " modules" << std::endl; - - // Get the main minetest table - lua_getglobal(L, "minetest"); - - // Add tables to minetest - lua_newtable(L); - lua_setfield(L, -2, "object_refs"); - - lua_newtable(L); - lua_setfield(L, -2, "luaentities"); -} - -ScriptApi::~ScriptApi() { - lua_close(getStack()); -} - -bool ScriptApi::scriptLoad(const char *path) -{ - lua_State* L = getStack(); - setStack(0); - - verbosestream<<"Loading and running script from "<<path<<std::endl; - - lua_pushcfunction(L, script_ErrorHandler); - int errorhandler = lua_gettop(L); - - int ret = luaL_loadfile(L, path) || lua_pcall(L, 0, 0, errorhandler); - if(ret){ - errorstream<<"========== ERROR FROM LUA ==========="<<std::endl; - errorstream<<"Failed to load and run script from "<<std::endl; - errorstream<<path<<":"<<std::endl; - errorstream<<std::endl; - errorstream<<lua_tostring(L, -1)<<std::endl; - errorstream<<std::endl; - errorstream<<"=======END OF ERROR FROM LUA ========"<<std::endl; - lua_pop(L, 1); // Pop error message from stack - lua_pop(L, 1); // Pop the error handler from stack - return false; - } - lua_pop(L, 1); // Pop the error handler from stack - return true; -} - -bool ScriptApi::registerModApiModule(ModApiBase* ptr) { - if (ScriptApi::m_mod_api_modules == 0) - ScriptApi::m_mod_api_modules = new std::vector<ModApiBase*>(); - - assert(ScriptApi::m_mod_api_modules != 0); - - ScriptApi::m_mod_api_modules->push_back(ptr); - - return true; -} - -std::vector<ModApiBase*>* ScriptApi::m_mod_api_modules = 0; |