SAPI: Track last executed mod and include in error messages
authorkwolekr <kwolekr@minetest.net>
Wed, 12 Aug 2015 02:27:54 +0000 (22:27 -0400)
committerkwolekr <kwolekr@minetest.net>
Thu, 13 Aug 2015 03:56:12 +0000 (23:56 -0400)
19 files changed:
builtin/game/auth.lua
builtin/game/chatcommands.lua
builtin/game/detached_inventory.lua
builtin/game/item.lua
builtin/game/misc.lua
builtin/game/register.lua
src/script/common/c_internal.cpp
src/script/common/c_internal.h
src/script/cpp_api/s_base.cpp
src/script/cpp_api/s_base.h
src/script/cpp_api/s_entity.cpp
src/script/cpp_api/s_env.cpp
src/script/cpp_api/s_inventory.cpp
src/script/cpp_api/s_item.cpp
src/script/cpp_api/s_player.cpp
src/script/cpp_api/s_server.cpp
src/script/lua_api/l_env.cpp
src/script/lua_api/l_server.cpp
src/script/lua_api/l_server.h

index 93b0099818afb9ebc6dd37b88ede5228ac3550ee..423eb3134a29964b1f23a7738df408b620ad432c 100644 (file)
@@ -171,6 +171,7 @@ function core.register_authentication_handler(handler)
        end
        core.registered_auth_handler = handler
        core.registered_auth_handler_modname = core.get_current_modname()
+       handler.mod_origin = core.registered_auth_handler_modname
 end
 
 function core.get_auth_handler()
index 6c8ca8699f63d3bf69c2c77b5f7aa07f9a3e9e28..5d317de4b870289c91db5b39e258f28138d25566 100644 (file)
@@ -10,6 +10,7 @@ function core.register_chatcommand(cmd, def)
        def.params = def.params or ""
        def.description = def.description or ""
        def.privs = def.privs or {}
+       def.mod_origin = core.get_current_modname() or "??"
        core.chatcommands[cmd] = def
 end
 
@@ -37,6 +38,7 @@ core.register_on_chat_message(function(name, message)
        end
        local has_privs, missing_privs = core.check_player_privs(name, cmd_def.privs)
        if has_privs then
+               core.set_last_run_mod(cmd_def.mod_origin)
                local success, message = cmd_def.func(name, param)
                if message then
                        core.chat_send_player(name, message)
index e8f03b56ce3b43466b759f3425d72c4cf7faf19a..b5d106b042ccfb13e963f0ba13aef45024bb9eab 100644 (file)
@@ -13,6 +13,7 @@ function core.create_detached_inventory(name, callbacks)
                stuff.on_put = callbacks.on_put
                stuff.on_take = callbacks.on_take
        end
+       stuff.mod_origin = core.get_current_modname() or "??"
        core.detached_inventories[name] = stuff
        return core.create_detached_inventory_raw(name)
 end
index d25f4eff0ecf79fe39443d62303c68d2c3b2448c..6628a40813ffef0be47561b11fb609800d1c97b2 100644 (file)
@@ -479,6 +479,15 @@ function core.node_dig(pos, node, digger)
        -- Run script hook
        local _, callback
        for _, callback in ipairs(core.registered_on_dignodes) do
+               local origin = core.callback_origins[callback]
+               if origin then
+                       core.set_last_run_mod(origin.mod)
+                       --print("Running " .. tostring(callback) ..
+                       --      " (a " .. origin.name .. " callback in " .. origin.mod .. ")")
+               else
+                       --print("No data associated with callback")
+               end
+
                -- Copy pos and node because callback can modify them
                local pos_copy = {x=pos.x, y=pos.y, z=pos.z}
                local node_copy = {name=node.name, param1=node.param1, param2=node.param2}
index 7fa95742e969a1896f4b654040405a8373b26192..e3b7d82bcc91966c5c7139ccdf0dc88726f132fd 100644 (file)
@@ -14,6 +14,7 @@ local function update_timers(delay)
                local timer = timers[index]
                timer.time = timer.time - delay
                if timer.time <= 0 then
+                       core.set_last_run_mod(timer.mod_origin)
                        timer.func(unpack(timer.args or {}))
                        table.remove(timers, index)
                        sub = sub + 1
@@ -55,12 +56,22 @@ function core.after(time, func, ...)
                        "Invalid core.after invocation")
        if not mintime then
                mintime = time
-               timers_to_add = {{time=time+delay, func=func, args={...}}}
+               timers_to_add = {{
+                       time   = time+delay,
+                       func   = func,
+                       args   = {...},
+                       mod_origin = core.get_last_run_mod(),
+               }}
                return
        end
        mintime = math.min(mintime, time)
        timers_to_add = timers_to_add or {}
-       timers_to_add[#timers_to_add+1] = {time=time+delay, func=func, args={...}}
+       timers_to_add[#timers_to_add+1] = {
+               time   = time+delay,
+               func   = func,
+               args   = {...},
+               mod_origin = core.get_last_run_mod(),
+       }
 end
 
 function core.check_player_privs(name, privs)
index 3a13abfb35e364b9fc71ce981d589a8a03da46ff..d0e04bfc37e1a80c172a923424530f5b09f18c7c 100644 (file)
@@ -72,6 +72,7 @@ end
 function core.register_abm(spec)
        -- Add to core.registered_abms
        core.registered_abms[#core.registered_abms+1] = spec
+       spec.mod_origin = core.get_current_modname() or "??"
 end
 
 function core.register_entity(name, prototype)
@@ -86,6 +87,7 @@ function core.register_entity(name, prototype)
 
        -- Add to core.registered_entities
        core.registered_entities[name] = prototype
+       prototype.mod_origin = core.get_current_modname() or "??"
 end
 
 function core.register_item(name, itemdef)
@@ -147,6 +149,8 @@ function core.register_item(name, itemdef)
        end
        -- END Legacy stuff
 
+       itemdef.mod_origin = core.get_current_modname() or "??"
+
        -- Disable all further modifications
        getmetatable(itemdef).__newindex = {}
 
@@ -326,6 +330,8 @@ function core.override_item(name, redefinition)
 end
 
 
+core.callback_origins = {}
+
 function core.run_callbacks(callbacks, mode, ...)
        assert(type(callbacks) == "table")
        local cb_len = #callbacks
@@ -338,6 +344,14 @@ function core.run_callbacks(callbacks, mode, ...)
        end
        local ret = nil
        for i = 1, cb_len do
+               local origin = core.callback_origins[callbacks[i]]
+               if origin then
+                       core.set_last_run_mod(origin.mod)
+                       --print("Running " .. tostring(callbacks[i]) ..
+                       --      " (a " .. origin.name .. " callback in " .. origin.mod .. ")")
+               else
+                       --print("No data associated with callback")
+               end
                local cb_ret = callbacks[i](...)
 
                if mode == 0 and i == 1 then
@@ -370,13 +384,29 @@ end
 
 local function make_registration()
        local t = {}
-       local registerfunc = function(func) table.insert(t, func) end
+       local registerfunc = function(func)
+               table.insert(t, func)
+               core.callback_origins[func] = {
+                       mod = core.get_current_modname() or "??",
+                       name = debug.getinfo(1, "n").name or "??"
+               }
+               --local origin = core.callback_origins[func]
+               --print(origin.name .. ": " .. origin.mod .. " registering cbk " .. tostring(func))
+       end
        return t, registerfunc
 end
 
 local function make_registration_reverse()
        local t = {}
-       local registerfunc = function(func) table.insert(t, 1, func) end
+       local registerfunc = function(func)
+               table.insert(t, 1, func)
+               core.callback_origins[func] = {
+                       mod = core.get_current_modname() or "??",
+                       name = debug.getinfo(1, "n").name or "??"
+               }
+               --local origin = core.callback_origins[func]
+               --print(origin.name .. ": " .. origin.mod .. " registering cbk " .. tostring(func))
+       end
        return t, registerfunc
 end
 
@@ -408,6 +438,7 @@ local function make_registration_wrap(reg_fn_name, clear_fn_name)
 end
 
 core.registered_on_player_hpchanges = { modifiers = { }, loggers = { } }
+
 function core.registered_on_player_hpchange(player, hp_change)
        local last = false
        for i = #core.registered_on_player_hpchanges.modifiers, 1, -1 do
@@ -427,12 +458,17 @@ function core.registered_on_player_hpchange(player, hp_change)
        end
        return hp_change
 end
+
 function core.register_on_player_hpchange(func, modifier)
        if modifier then
                table.insert(core.registered_on_player_hpchanges.modifiers, func)
        else
                table.insert(core.registered_on_player_hpchanges.loggers, func)
        end
+       core.callback_origins[func] = {
+               mod = core.get_current_modname() or "??",
+               name = debug.getinfo(1, "n").name or "??"
+       }
 end
 
 core.registered_biomes      = make_registration_wrap("register_biome",      "clear_registered_biomes")
index 0df0a72702055241842251a0ddf39e555b353436..2a10ce0f25050ab1d1026646f568815e6834e1a3 100644 (file)
@@ -79,7 +79,7 @@ int script_exception_wrapper(lua_State *L, lua_CFunction f)
  * to gather a coherent backtrace.  Realistically, the best we can do here is
  * print which C function performed the failing pcall.
  */
-void script_error(lua_State *L, int pcall_result, const char *fxn)
+void script_error(lua_State *L, int pcall_result, const char *mod, const char *fxn)
 {
        if (pcall_result == 0)
                return;
@@ -99,18 +99,21 @@ void script_error(lua_State *L, int pcall_result, const char *fxn)
                err_type = "Unknown";
        }
 
+       if (!mod)
+               mod = "??";
+
+       if (!fxn)
+               fxn = "??";
+
        const char *err_descr = lua_tostring(L, -1);
        if (!err_descr)
                err_descr = "<no description>";
 
-       std::string err_msg(err_type);
-       if (fxn) {
-               err_msg += " error in ";
-               err_msg += fxn;
-               err_msg += "(): ";
-       } else {
-               err_msg += " error: ";
-       }
+       char buf[256];
+       snprintf(buf, sizeof(buf), "%s error from mod '%s' in callback %s(): ",
+               err_type, mod, fxn);
+
+       std::string err_msg(buf);
        err_msg += err_descr;
 
        if (pcall_result == LUA_ERRMEM) {
@@ -152,7 +155,7 @@ void script_run_callbacks_f(lua_State *L, int nargs,
 
        int result = lua_pcall(L, nargs + 2, 1, errorhandler);
        if (result != 0)
-               script_error(L, result, fxn);
+               script_error(L, result, NULL, fxn);
 
        lua_remove(L, -2); // Remove error handler
 }
@@ -176,7 +179,7 @@ void log_deprecated(lua_State *L, const std::string &message)
 
        if (doerror) {
                if (L != NULL) {
-                       script_error(L, LUA_ERRRUN, NULL);
+                       script_error(L, LUA_ERRRUN, NULL, NULL);
                } else {
                        FATAL_ERROR("Can't do a scripterror for this deprecated message, "
                                "so exit completely!");
index 54cdd7da7bcd542f8ca6471b50b80be8e2e1ba45..ecb514c8fb8f95cbb84293d387221af2bf1d4a29 100644 (file)
@@ -34,11 +34,11 @@ extern "C" {
 
 #include "common/c_types.h"
 
-#define PCALL_RESL(L, RES) do {                   \
-       int result_ = (RES);                          \
-       if (result_ != 0) {                           \
-               script_error((L), result_, __FUNCTION__); \
-       }                                             \
+#define PCALL_RESL(L, RES) do {                         \
+       int result_ = (RES);                                \
+       if (result_ != 0) {                                 \
+               script_error((L), result_, NULL, __FUNCTION__); \
+       }                                                   \
 } while (0)
 
 #define script_run_callbacks(L, nargs, mode) \
@@ -77,7 +77,7 @@ enum RunCallbacksMode
 std::string script_get_backtrace(lua_State *L);
 int script_error_handler(lua_State *L);
 int script_exception_wrapper(lua_State *L, lua_CFunction f);
-void script_error(lua_State *L, int pcall_result, const char *fxn);
+void script_error(lua_State *L, int pcall_result, const char *mod, const char *fxn);
 void script_run_callbacks_f(lua_State *L, int nargs,
        RunCallbacksMode mode, const char *fxn);
 void log_deprecated(lua_State *L, const std::string &message);
index 680e661ea3f5df470582a3ff72ae7597c0d8a72d..dcfbac4bfe99468fb1db73e395fb2e248489eebd 100644 (file)
@@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "cpp_api/s_internal.h"
 #include "cpp_api/s_security.h"
 #include "lua_api/l_object.h"
+#include "common/c_converter.h"
 #include "serverobject.h"
 #include "debug.h"
 #include "filesys.h"
@@ -68,9 +69,9 @@ public:
 
 ScriptApiBase::ScriptApiBase()
 {
-       #ifdef SCRIPTAPI_LOCK_DEBUG
+#ifdef SCRIPTAPI_LOCK_DEBUG
        m_locked = false;
-       #endif
+#endif
 
        m_luastack = luaL_newstate();
        FATAL_ERROR_IF(!m_luastack, "luaL_newstate() failed");
@@ -154,6 +155,43 @@ bool ScriptApiBase::loadScript(const std::string &script_path, std::string *erro
        return true;
 }
 
+// Push the list of callbacks (a lua table).
+// Then push nargs arguments.
+// Then call this function, which
+// - runs the callbacks
+// - replaces the table and arguments with the return value,
+//     computed depending on mode
+void ScriptApiBase::runCallbacksRaw(int nargs,
+               RunCallbacksMode mode, const char *fxn)
+{
+       lua_State *L = getStack();
+       FATAL_ERROR_IF(lua_gettop(L) < nargs + 1, "Not enough arguments");
+
+       // Insert error handler
+       lua_pushcfunction(L, script_error_handler);
+       int errorhandler = lua_gettop(L) - nargs - 1;
+       lua_insert(L, errorhandler);
+
+       // Insert run_callbacks between error handler and table
+       lua_getglobal(L, "core");
+       lua_getfield(L, -1, "run_callbacks");
+       lua_remove(L, -2);
+       lua_insert(L, errorhandler + 1);
+
+       // Insert mode after table
+       lua_pushnumber(L, (int)mode);
+       lua_insert(L, errorhandler + 3);
+
+       // Stack now looks like this:
+       // ... <error handler> <run_callbacks> <table> <mode> <arg#1> <arg#2> ... <arg#n>
+
+       int result = lua_pcall(L, nargs + 2, 1, errorhandler);
+       if (result != 0)
+               scriptError(result, fxn);
+
+       lua_remove(L, -2); // Remove error handler
+}
+
 void ScriptApiBase::realityCheck()
 {
        int top = lua_gettop(m_luastack);
@@ -167,7 +205,7 @@ void ScriptApiBase::realityCheck()
 
 void ScriptApiBase::scriptError(int result, const char *fxn)
 {
-       script_error(getStack(), result, fxn);
+       script_error(getStack(), result, m_last_run_mod.c_str(), fxn);
 }
 
 void ScriptApiBase::stackDump(std::ostream &o)
@@ -197,6 +235,22 @@ void ScriptApiBase::stackDump(std::ostream &o)
        o << std::endl;
 }
 
+void ScriptApiBase::setOriginDirect(const char *origin)
+{
+       m_last_run_mod = origin ? origin : "??";
+}
+
+void ScriptApiBase::setOriginFromTableRaw(int index, const char *fxn)
+{
+#ifdef SCRIPTAPI_DEBUG
+       lua_State *L = getStack();
+
+       m_last_run_mod = lua_istable(L, index) ?
+               getstringfield_default(L, index, "mod_origin", "") : "";
+       //printf(">>>> running %s for mod: %s\n", fxn, m_last_run_mod.c_str());
+#endif
+}
+
 void ScriptApiBase::addObjectReference(ServerActiveObject *cobj)
 {
        SCRIPTAPI_PRECHECKHEADER
index 0c2dfafd1f9f9fdec4cd97d82d3965e0f1591cb4..d653b5bacb8d70b7f6edf5859ef316cc92f94275 100644 (file)
@@ -34,6 +34,7 @@ extern "C" {
 #include "common/c_internal.h"
 
 #define SCRIPTAPI_LOCK_DEBUG
+#define SCRIPTAPI_DEBUG
 
 #define SCRIPT_MOD_NAME_FIELD "current_mod_name"
 // MUST be an invalid mod name so that mods can't
@@ -47,6 +48,12 @@ extern "C" {
        }                                       \
 } while (0)
 
+#define runCallbacks(nargs, mode) \
+       runCallbacksRaw((nargs), (mode), __FUNCTION__)
+
+#define setOriginFromTable(index) \
+       setOriginFromTableRaw(index, __FUNCTION__)
+
 class Server;
 class Environment;
 class GUIEngine;
@@ -61,12 +68,19 @@ public:
                std::string *error=NULL);
        bool loadScript(const std::string &script_path, std::string *error=NULL);
 
+       void runCallbacksRaw(int nargs,
+               RunCallbacksMode mode, const char *fxn);
+
        /* object */
        void addObjectReference(ServerActiveObject *cobj);
        void removeObjectReference(ServerActiveObject *cobj);
 
        Server* getServer() { return m_server; }
 
+       std::string getOrigin() { return m_last_run_mod; }
+       void setOriginDirect(const char *origin);
+       void setOriginFromTableRaw(int index, const char *fxn);
+
 protected:
        friend class LuaABM;
        friend class InvRef;
@@ -95,6 +109,7 @@ protected:
        void objectrefGet(lua_State *L, u16 id);
 
        JMutex          m_luastackmutex;
+       std::string     m_last_run_mod;
        // Stack index of Lua error handler
        int             m_errorhandler;
        bool            m_secure;
index 08e06ccbcef499817f25ff0fe4041a7f097151bd..0d159846a0b6662ce1422d6dac425a1dce0a9ed2 100644 (file)
@@ -91,7 +91,8 @@ void ScriptApiEntity::luaentity_Activate(u16 id,
                lua_pushvalue(L, object); // self
                lua_pushlstring(L, staticdata.c_str(), staticdata.size());
                lua_pushinteger(L, dtime_s);
-               // Call with 3 arguments, 0 results
+
+               setOriginFromTable(object);
                PCALL_RES(lua_pcall(L, 3, 0, m_errorhandler));
        } else {
                lua_pop(L, 1);
@@ -135,11 +136,12 @@ std::string ScriptApiEntity::luaentity_GetStaticdata(u16 id)
                lua_pop(L, 2); // Pop entity and  get_staticdata
                return "";
        }
-
        luaL_checktype(L, -1, LUA_TFUNCTION);
        lua_pushvalue(L, object); // self
-       // Call with 1 arguments, 1 results
+
+       setOriginFromTable(object);
        PCALL_RES(lua_pcall(L, 1, 1, m_errorhandler));
+
        lua_remove(L, object); // Remove object
 
        size_t len = 0;
@@ -207,8 +209,10 @@ void ScriptApiEntity::luaentity_Step(u16 id, float dtime)
        luaL_checktype(L, -1, LUA_TFUNCTION);
        lua_pushvalue(L, object); // self
        lua_pushnumber(L, dtime); // dtime
-       // Call with 2 arguments, 0 results
+
+       setOriginFromTable(object);
        PCALL_RES(lua_pcall(L, 2, 0, m_errorhandler));
+
        lua_pop(L, 1); // Pop object
 }
 
@@ -238,8 +242,10 @@ void ScriptApiEntity::luaentity_Punch(u16 id,
        lua_pushnumber(L, time_from_last_punch);
        push_tool_capabilities(L, *toolcap);
        push_v3f(L, dir);
-       // Call with 5 arguments, 0 results
+
+       setOriginFromTable(object);
        PCALL_RES(lua_pcall(L, 5, 0, m_errorhandler));
+
        lua_pop(L, 1); // Pop object
 }
 
@@ -264,8 +270,10 @@ void ScriptApiEntity::luaentity_Rightclick(u16 id,
        luaL_checktype(L, -1, LUA_TFUNCTION);
        lua_pushvalue(L, object); // self
        objectrefGetOrCreate(L, clicker); // Clicker reference
-       // Call with 2 arguments, 0 results
+
+       setOriginFromTable(object);
        PCALL_RES(lua_pcall(L, 2, 0, m_errorhandler));
+
        lua_pop(L, 1); // Pop object
 }
 
index c171bbf0249776d6789703ce8c78dbcfb1c33dc1..9c733773a6d14ed8ab11cf3e5663f5d08b0982d6 100644 (file)
@@ -38,7 +38,7 @@ void ScriptApiEnv::environment_OnGenerated(v3s16 minp, v3s16 maxp,
        push_v3s16(L, minp);
        push_v3s16(L, maxp);
        lua_pushnumber(L, blockseed);
-       script_run_callbacks(L, 3, RUN_CALLBACKS_MODE_FIRST);
+       runCallbacks(3, RUN_CALLBACKS_MODE_FIRST);
 }
 
 void ScriptApiEnv::environment_Step(float dtime)
@@ -52,7 +52,7 @@ void ScriptApiEnv::environment_Step(float dtime)
        // Call callbacks
        lua_pushnumber(L, dtime);
        try {
-               script_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST);
+               runCallbacks(1, RUN_CALLBACKS_MODE_FIRST);
        } catch (LuaError &e) {
                getServer()->setAsyncFatalError(e.what());
        }
@@ -73,7 +73,7 @@ void ScriptApiEnv::player_event(ServerActiveObject* player, std::string type)
        objectrefGetOrCreate(L, player);   // player
        lua_pushstring(L,type.c_str()); // event type
        try {
-               script_run_callbacks(L, 2, RUN_CALLBACKS_MODE_FIRST);
+               runCallbacks(2, RUN_CALLBACKS_MODE_FIRST);
        } catch (LuaError &e) {
                getServer()->setAsyncFatalError(e.what());
        }
index c8c90fd8f1f69bddd5a177eee9de25c8b2353f14..019d1ccc07deeae8b4f6a5776b8d482ced12caed 100644 (file)
@@ -209,6 +209,9 @@ bool ScriptApiDetached::getDetachedInventoryCallback(
                lua_pop(L, 1);
                return false;
        }
+
+       setOriginFromTable(-1);
+
        lua_getfield(L, -1, callbackname);
        lua_remove(L, -2);
        // Should be a function or nil
index 1ca06de7646af2a4a16549df7b2bce391c5b83da..4d4d416ec7ad33639cd2f37d11931d0961abda21 100644 (file)
@@ -193,6 +193,9 @@ bool ScriptApiItem::getItemCallback(const char *name, const char *callbackname)
                lua_remove(L, -2);
                luaL_checktype(L, -1, LUA_TTABLE);
        }
+
+       setOriginFromTable(-1);
+
        lua_getfield(L, -1, callbackname);
        lua_remove(L, -2); // Remove item def
        // Should be a function or nil
index 676b07537345e6f0b3d357025fc04559dc6844a4..ef3c31cfd2cdcb0b4ee42bab36f76d5b7a30440c 100644 (file)
@@ -32,7 +32,7 @@ void ScriptApiPlayer::on_newplayer(ServerActiveObject *player)
        lua_getfield(L, -1, "registered_on_newplayers");
        // Call callbacks
        objectrefGetOrCreate(L, player);
-       script_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST);
+       runCallbacks(1, RUN_CALLBACKS_MODE_FIRST);
 }
 
 void ScriptApiPlayer::on_dieplayer(ServerActiveObject *player)
@@ -44,7 +44,7 @@ void ScriptApiPlayer::on_dieplayer(ServerActiveObject *player)
        lua_getfield(L, -1, "registered_on_dieplayers");
        // Call callbacks
        objectrefGetOrCreate(L, player);
-       script_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST);
+       runCallbacks(1, RUN_CALLBACKS_MODE_FIRST);
 }
 
 bool ScriptApiPlayer::on_punchplayer(ServerActiveObject *player,
@@ -65,7 +65,7 @@ bool ScriptApiPlayer::on_punchplayer(ServerActiveObject *player,
        push_tool_capabilities(L, *toolcap);
        push_v3f(L, dir);
        lua_pushnumber(L, damage);
-       script_run_callbacks(L, 6, RUN_CALLBACKS_MODE_OR);
+       runCallbacks(6, RUN_CALLBACKS_MODE_OR);
        return lua_toboolean(L, -1);
 }
 
@@ -96,7 +96,7 @@ bool ScriptApiPlayer::on_respawnplayer(ServerActiveObject *player)
        lua_getfield(L, -1, "registered_on_respawnplayers");
        // Call callbacks
        objectrefGetOrCreate(L, player);
-       script_run_callbacks(L, 1, RUN_CALLBACKS_MODE_OR);
+       runCallbacks(1, RUN_CALLBACKS_MODE_OR);
        bool positioning_handled_by_some = lua_toboolean(L, -1);
        return positioning_handled_by_some;
 }
@@ -113,7 +113,7 @@ bool ScriptApiPlayer::on_prejoinplayer(
        lua_getfield(L, -1, "registered_on_prejoinplayers");
        lua_pushstring(L, name.c_str());
        lua_pushstring(L, ip.c_str());
-       script_run_callbacks(L, 2, RUN_CALLBACKS_MODE_OR);
+       runCallbacks(2, RUN_CALLBACKS_MODE_OR);
        if (lua_isstring(L, -1)) {
                reason->assign(lua_tostring(L, -1));
                return true;
@@ -130,7 +130,7 @@ void ScriptApiPlayer::on_joinplayer(ServerActiveObject *player)
        lua_getfield(L, -1, "registered_on_joinplayers");
        // Call callbacks
        objectrefGetOrCreate(L, player);
-       script_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST);
+       runCallbacks(1, RUN_CALLBACKS_MODE_FIRST);
 }
 
 void ScriptApiPlayer::on_leaveplayer(ServerActiveObject *player)
@@ -142,7 +142,7 @@ void ScriptApiPlayer::on_leaveplayer(ServerActiveObject *player)
        lua_getfield(L, -1, "registered_on_leaveplayers");
        // Call callbacks
        objectrefGetOrCreate(L, player);
-       script_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST);
+       runCallbacks(1, RUN_CALLBACKS_MODE_FIRST);
 }
 
 void ScriptApiPlayer::on_cheat(ServerActiveObject *player,
@@ -158,7 +158,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");
-       script_run_callbacks(L, 2, RUN_CALLBACKS_MODE_FIRST);
+       runCallbacks(2, RUN_CALLBACKS_MODE_FIRST);
 }
 
 void ScriptApiPlayer::on_playerReceiveFields(ServerActiveObject *player,
@@ -185,7 +185,7 @@ void ScriptApiPlayer::on_playerReceiveFields(ServerActiveObject *player,
                lua_pushlstring(L, value.c_str(), value.size());
                lua_settable(L, -3);
        }
-       script_run_callbacks(L, 3, RUN_CALLBACKS_MODE_OR_SC);
+       runCallbacks(3, RUN_CALLBACKS_MODE_OR_SC);
 }
 
 ScriptApiPlayer::~ScriptApiPlayer()
index 5b4626f40943c35638693234795f927a410aae6e..ec2f9c0af879ac5415cf938ec5dafac81d8ef198 100644 (file)
@@ -67,6 +67,9 @@ void ScriptApiServer::getAuthHandler()
                lua_pop(L, 1);
                lua_getfield(L, -1, "builtin_auth_handler");
        }
+
+       setOriginFromTable(-1);
+
        lua_remove(L, -2); // Remove core
        if (lua_type(L, -1) != LUA_TTABLE)
                throw LuaError("Authentication handler table not valid");
@@ -133,7 +136,7 @@ bool ScriptApiServer::on_chat_message(const std::string &name,
        // Call callbacks
        lua_pushstring(L, name.c_str());
        lua_pushstring(L, message.c_str());
-       script_run_callbacks(L, 2, RUN_CALLBACKS_MODE_OR_SC);
+       runCallbacks(2, RUN_CALLBACKS_MODE_OR_SC);
        bool ate = lua_toboolean(L, -1);
        return ate;
 }
@@ -146,6 +149,6 @@ void ScriptApiServer::on_shutdown()
        lua_getglobal(L, "core");
        lua_getfield(L, -1, "registered_on_shutdown");
        // Call callbacks
-       script_run_callbacks(L, 0, RUN_CALLBACKS_MODE_FIRST);
+       runCallbacks(0, RUN_CALLBACKS_MODE_FIRST);
 }
 
index 48c46c07999e1d0e469980e7a917ec7d83b0806d..9d1936769192d03c8f03dbcc59297d7541ed94ad 100644 (file)
@@ -68,6 +68,8 @@ void LuaABM::trigger(ServerEnvironment *env, v3s16 p, MapNode n,
                FATAL_ERROR("");
        lua_remove(L, -2); // Remove registered_abms
 
+       scriptIface->setOriginFromTable(-1);
+
        // Call action
        luaL_checktype(L, -1, LUA_TTABLE);
        lua_getfield(L, -1, "action");
@@ -78,7 +80,9 @@ void LuaABM::trigger(ServerEnvironment *env, v3s16 p, MapNode n,
        lua_pushnumber(L, active_object_count);
        lua_pushnumber(L, active_object_count_wider);
 
-       PCALL_RESL(L, lua_pcall(L, 4, 0, errorhandler));
+       int result = lua_pcall(L, 4, 0, errorhandler);
+       if (result)
+               scriptIface->scriptError(result, "LuaABM::trigger");
 
        lua_pop(L, 1); // Pop error handler
 }
index 96c0327df0e9dff6c3ed529b085c54a27a03c4c7..73eca9d6099d533c8bfc744d47b24468f63f9b11 100644 (file)
@@ -438,6 +438,31 @@ int ModApiServer::l_notify_authentication_modified(lua_State *L)
        return 0;
 }
 
+// get_last_run_mod()
+int ModApiServer::l_get_last_run_mod(lua_State *L)
+{
+       NO_MAP_LOCK_REQUIRED;
+       lua_getfield(L, LUA_REGISTRYINDEX, SCRIPT_MOD_NAME_FIELD);
+       const char *current_mod = lua_tostring(L, -1);
+       if (current_mod == NULL || current_mod[0] == '\0') {
+               lua_pop(L, 1);
+               lua_pushstring(L, getScriptApiBase(L)->getOrigin().c_str());
+       }
+       return 1;
+}
+
+// set_last_run_mod(modname)
+int ModApiServer::l_set_last_run_mod(lua_State *L)
+{
+       NO_MAP_LOCK_REQUIRED;
+#ifdef SCRIPTAPI_DEBUG
+       const char *mod = lua_tostring(L, 1);
+       getScriptApiBase(L)->setOriginDirect(mod);
+       //printf(">>>> last mod set from Lua: %s\n", mod);
+#endif
+       return 0;
+}
+
 #ifndef NDEBUG
 // cause_error(type_of_error)
 int ModApiServer::l_cause_error(lua_State *L)
@@ -495,6 +520,8 @@ void ModApiServer::Initialize(lua_State *L, int top)
        API_FCT(unban_player_or_ip);
        API_FCT(notify_authentication_modified);
 
+       API_FCT(get_last_run_mod);
+       API_FCT(set_last_run_mod);
 #ifndef NDEBUG
        API_FCT(cause_error);
 #endif
index e14bef043a8a1005d065036808894b9f4a413bf8..df31f325f03281f323a03e29f1bb2f0532cb23b4 100644 (file)
@@ -88,6 +88,12 @@ private:
        // notify_authentication_modified(name)
        static int l_notify_authentication_modified(lua_State *L);
 
+       // get_last_run_mod()
+       static int l_get_last_run_mod(lua_State *L);
+
+       // set_last_run_mod(modname)
+       static int l_set_last_run_mod(lua_State *L);
+
 #ifndef NDEBUG
        //  cause_error(type_of_error)
        static int l_cause_error(lua_State *L);