diff --git a/builtin/game/auth.lua b/builtin/game/auth.lua index 93b009981..bb0918986 100644 --- a/builtin/game/auth.lua +++ b/builtin/game/auth.lua @@ -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() + core.origin = core.registered_auth_handler_modname end function core.get_auth_handler() diff --git a/builtin/game/chatcommands.lua b/builtin/game/chatcommands.lua index 6c8ca8699..f0851a6bf 100644 --- a/builtin/game/chatcommands.lua +++ b/builtin/game/chatcommands.lua @@ -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.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.origin) local success, message = cmd_def.func(name, param) if message then core.chat_send_player(name, message) diff --git a/builtin/game/detached_inventory.lua b/builtin/game/detached_inventory.lua index e8f03b56c..1085e7733 100644 --- a/builtin/game/detached_inventory.lua +++ b/builtin/game/detached_inventory.lua @@ -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.origin = core.get_current_modname() or "??" core.detached_inventories[name] = stuff return core.create_detached_inventory_raw(name) end diff --git a/builtin/game/item.lua b/builtin/game/item.lua index d25f4eff0..8d2ad0d12 100644 --- a/builtin/game/item.lua +++ b/builtin/game/item.lua @@ -479,6 +479,16 @@ 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} diff --git a/builtin/game/misc.lua b/builtin/game/misc.lua index 7fa95742e..7291dff35 100644 --- a/builtin/game/misc.lua +++ b/builtin/game/misc.lua @@ -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.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 = {...}, + 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 = {...}, + origin = core.get_last_run_mod(), + } end function core.check_player_privs(name, privs) diff --git a/builtin/game/register.lua b/builtin/game/register.lua index 3a13abfb3..7192fb455 100644 --- a/builtin/game/register.lua +++ b/builtin/game/register.lua @@ -72,6 +72,7 @@ end function core.register_abm(spec) -- Add to core.registered_abms core.registered_abms[#core.registered_abms+1] = spec + spec.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.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.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") diff --git a/src/script/common/c_internal.cpp b/src/script/common/c_internal.cpp index 0df0a7270..2a10ce0f2 100644 --- a/src/script/common/c_internal.cpp +++ b/src/script/common/c_internal.cpp @@ -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 = ""; - 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!"); diff --git a/src/script/common/c_internal.h b/src/script/common/c_internal.h index 54cdd7da7..ecb514c8f 100644 --- a/src/script/common/c_internal.h +++ b/src/script/common/c_internal.h @@ -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); diff --git a/src/script/cpp_api/s_base.cpp b/src/script/cpp_api/s_base.cpp index 680e661ea..52d91204a 100644 --- a/src/script/cpp_api/s_base.cpp +++ b/src/script/cpp_api/s_base.cpp @@ -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: + // ... ... + + 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,25 @@ 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(); + + if (index < 0) + index = lua_gettop(L) + 1 + index; + + m_last_run_mod = lua_istable(L, index) ? + getstringfield_default(L, index, "origin", "") : ""; + //printf(">>>> running %s for mod: %s\n", fxn, m_last_run_mod.c_str()); +#endif +} + void ScriptApiBase::addObjectReference(ServerActiveObject *cobj) { SCRIPTAPI_PRECHECKHEADER diff --git a/src/script/cpp_api/s_base.h b/src/script/cpp_api/s_base.h index 0c2dfafd1..d653b5bac 100644 --- a/src/script/cpp_api/s_base.h +++ b/src/script/cpp_api/s_base.h @@ -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; diff --git a/src/script/cpp_api/s_entity.cpp b/src/script/cpp_api/s_entity.cpp index 08e06ccbc..0d159846a 100644 --- a/src/script/cpp_api/s_entity.cpp +++ b/src/script/cpp_api/s_entity.cpp @@ -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 } diff --git a/src/script/cpp_api/s_env.cpp b/src/script/cpp_api/s_env.cpp index c171bbf02..9c733773a 100644 --- a/src/script/cpp_api/s_env.cpp +++ b/src/script/cpp_api/s_env.cpp @@ -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()); } diff --git a/src/script/cpp_api/s_inventory.cpp b/src/script/cpp_api/s_inventory.cpp index c8c90fd8f..019d1ccc0 100644 --- a/src/script/cpp_api/s_inventory.cpp +++ b/src/script/cpp_api/s_inventory.cpp @@ -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 diff --git a/src/script/cpp_api/s_item.cpp b/src/script/cpp_api/s_item.cpp index 1ca06de76..4d4d416ec 100644 --- a/src/script/cpp_api/s_item.cpp +++ b/src/script/cpp_api/s_item.cpp @@ -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 diff --git a/src/script/cpp_api/s_player.cpp b/src/script/cpp_api/s_player.cpp index 676b07537..ef3c31cfd 100644 --- a/src/script/cpp_api/s_player.cpp +++ b/src/script/cpp_api/s_player.cpp @@ -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() diff --git a/src/script/cpp_api/s_server.cpp b/src/script/cpp_api/s_server.cpp index 5b4626f40..ec2f9c0af 100644 --- a/src/script/cpp_api/s_server.cpp +++ b/src/script/cpp_api/s_server.cpp @@ -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); } diff --git a/src/script/lua_api/l_env.cpp b/src/script/lua_api/l_env.cpp index 48c46c079..9d1936769 100644 --- a/src/script/lua_api/l_env.cpp +++ b/src/script/lua_api/l_env.cpp @@ -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 } diff --git a/src/script/lua_api/l_server.cpp b/src/script/lua_api/l_server.cpp index 96c0327df..73eca9d60 100644 --- a/src/script/lua_api/l_server.cpp +++ b/src/script/lua_api/l_server.cpp @@ -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 diff --git a/src/script/lua_api/l_server.h b/src/script/lua_api/l_server.h index e14bef043..df31f325f 100644 --- a/src/script/lua_api/l_server.h +++ b/src/script/lua_api/l_server.h @@ -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);