15 changes: 15 additions & 0 deletions src/script/cpp_api/s_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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;
Expand All @@ -61,12 +68,19 @@ class ScriptApiBase {
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;
Expand Down Expand Up @@ -95,6 +109,7 @@ class ScriptApiBase {
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;
Expand Down
20 changes: 14 additions & 6 deletions src/script/cpp_api/s_entity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
}

Expand Down Expand Up @@ -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
}

Expand All @@ -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
}

6 changes: 3 additions & 3 deletions src/script/cpp_api/s_env.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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());
}
Expand All @@ -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());
}
Expand Down
3 changes: 3 additions & 0 deletions src/script/cpp_api/s_inventory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions src/script/cpp_api/s_item.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
18 changes: 9 additions & 9 deletions src/script/cpp_api/s_player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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,
Expand All @@ -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);
}

Expand Down Expand Up @@ -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;
}
Expand All @@ -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;
Expand All @@ -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)
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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()
Expand Down
7 changes: 5 additions & 2 deletions src/script/cpp_api/s_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down Expand Up @@ -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;
}
Expand All @@ -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);
}

6 changes: 5 additions & 1 deletion src/script/lua_api/l_env.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand All @@ -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");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you hardcode the function name here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because:

  • trigger on its own is too vague, since __FUNCTION__ only includes the function name and not the class
  • this uses ScriptApiBase::scriptError() is being used externally so the macro PCALL_RES() won't work. I could write __FUNCTION__ here, but what's the point if this exact piece of code is being used in exactly one function??

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't get a warning if the function gets renamed. We had lots of copy paste in the networking code, and the functions got renamed without the logging getting fixed.


lua_pop(L, 1); // Pop error handler
}
Expand Down
27 changes: 27 additions & 0 deletions src/script/lua_api/l_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down
6 changes: 6 additions & 0 deletions src/script/lua_api/l_server.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,12 @@ class ModApiServer : public ModApiBase {
// 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);
Expand Down