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);
+ PUSH_ERROR_HANDLER(L);
+ int error_handler = lua_gettop(L) - nargs - 1;
+ lua_insert(L, error_handler);
// 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);
+ lua_insert(L, error_handler + 1);
// Insert mode after table
lua_pushnumber(L, (int) mode);
- lua_insert(L, errorhandler + 3);
+ lua_insert(L, error_handler + 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);
+ int result = lua_pcall(L, nargs + 2, 1, error_handler);
if (result != 0)
script_error(L, result, NULL, fxn);
- lua_remove(L, -2); // Remove error handler
+ lua_remove(L, error_handler);
}
void log_deprecated(lua_State *L, const std::string &message)
#define CUSTOM_RIDX_SCRIPTAPI (CUSTOM_RIDX_BASE)
#define CUSTOM_RIDX_GLOBALS_BACKUP (CUSTOM_RIDX_BASE + 1)
#define CUSTOM_RIDX_CURRENT_MOD_NAME (CUSTOM_RIDX_BASE + 2)
+#define CUSTOM_RIDX_ERROR_HANDLER (CUSTOM_RIDX_BASE + 3)
+// Pushes the error handler onto the stack and returns its index
+#define PUSH_ERROR_HANDLER(L) \
+ (lua_rawgeti((L), LUA_REGISTRYINDEX, CUSTOM_RIDX_ERROR_HANDLER), lua_gettop((L)))
#define PCALL_RESL(L, RES) do { \
int result_ = (RES); \
}
/******************************************************************************/
-void AsyncEngine::step(lua_State *L, int errorhandler)
+void AsyncEngine::step(lua_State *L)
{
+ int error_handler = PUSH_ERROR_HANDLER(L);
lua_getglobal(L, "core");
resultQueueMutex.lock();
while (!resultQueue.empty()) {
lua_pushlstring(L, jobDone.serializedResult.data(),
jobDone.serializedResult.size());
- PCALL_RESL(L, lua_pcall(L, 2, 0, errorhandler));
+ PCALL_RESL(L, lua_pcall(L, 2, 0, error_handler));
}
resultQueueMutex.unlock();
- lua_pop(L, 1); // Pop core
+ lua_pop(L, 2); // Pop core and error handler
}
/******************************************************************************/
abort();
}
+ int error_handler = PUSH_ERROR_HANDLER(L);
+
lua_getglobal(L, "core");
if (lua_isnil(L, -1)) {
errorstream << "Unable to find core within async environment!";
toProcess.serializedParams.data(),
toProcess.serializedParams.size());
- int result = lua_pcall(L, 2, 1, m_errorhandler);
+ int result = lua_pcall(L, 2, 1, error_handler);
if (result) {
PCALL_RES(result);
toProcess.serializedResult = "";
jobDispatcher->putJobResult(toProcess);
}
- lua_pop(L, 1); // Pop core
+ lua_pop(L, 2); // Pop core and error handler
return 0;
}
* Engine step to process finished jobs
* the engine step is one way to pass events back, PushFinishedJobs another
* @param L The Lua stack
- * @param errorhandler Stack index of the Lua error handler
*/
- void step(lua_State *L, int errorhandler);
+ void step(lua_State *L);
/**
* Push a list of finished jobs onto the stack
luaL_openlibs(m_luastack);
- // Add and save an error handler
- lua_pushcfunction(m_luastack, script_error_handler);
- m_errorhandler = lua_gettop(m_luastack);
-
// Make the ScriptApiBase* accessible to ModApiBase
lua_pushlightuserdata(m_luastack, this);
lua_rawseti(m_luastack, LUA_REGISTRYINDEX, CUSTOM_RIDX_SCRIPTAPI);
+ // Add and save an error handler
+ lua_pushcfunction(m_luastack, script_error_handler);
+ lua_rawseti(m_luastack, LUA_REGISTRYINDEX, CUSTOM_RIDX_ERROR_HANDLER);
+
// If we are using LuaJIT add a C++ wrapper function to catch
// exceptions thrown in Lua -> C++ calls
#if USE_LUAJIT
lua_State *L = getStack();
+ int error_handler = PUSH_ERROR_HANDLER(L);
+
bool ok;
if (m_secure) {
ok = ScriptApiSecurity::safeLoadFile(L, script_path.c_str());
} else {
ok = !luaL_loadfile(L, script_path.c_str());
}
- ok = ok && !lua_pcall(L, 0, 0, m_errorhandler);
+ ok = ok && !lua_pcall(L, 0, 0, error_handler);
if (!ok) {
std::string error_msg = lua_tostring(L, -1);
if (error)
<< error_msg << std::endl << std::endl
<< "======= END OF ERROR FROM LUA ========" << std::endl;
lua_pop(L, 1); // Pop error message from stack
- return false;
}
- return true;
+ lua_pop(L, 1); // Pop error handler
+ return ok;
}
// Push the list of callbacks (a lua table).
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);
+ PUSH_ERROR_HANDLER(L);
+ int error_handler = lua_gettop(L) - nargs - 1;
+ lua_insert(L, error_handler);
// 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);
+ lua_insert(L, error_handler + 1);
// Insert mode after table
lua_pushnumber(L, (int)mode);
- lua_insert(L, errorhandler + 3);
+ lua_insert(L, error_handler + 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);
+ int result = lua_pcall(L, nargs + 2, 1, error_handler);
if (result != 0)
scriptError(result, fxn);
- lua_remove(L, -2); // Remove error handler
+ lua_remove(L, error_handler);
}
void ScriptApiBase::realityCheck()
Mutex m_luastackmutex;
std::string m_last_run_mod;
- // Stack index of Lua error handler
- int m_errorhandler;
bool m_secure;
#ifdef SCRIPTAPI_LOCK_DEBUG
bool m_locked;
verbosestream << "scriptapi_luaentity_activate: id=" << id << std::endl;
+ int error_handler = PUSH_ERROR_HANDLER(L);
+
// Get core.luaentities[id]
luaentity_get(L, id);
int object = lua_gettop(L);
lua_pushinteger(L, dtime_s);
setOriginFromTable(object);
- PCALL_RES(lua_pcall(L, 3, 0, m_errorhandler));
+ PCALL_RES(lua_pcall(L, 3, 0, error_handler));
} else {
lua_pop(L, 1);
}
- lua_pop(L, 1); // Pop object
+ lua_pop(L, 2); // Pop object and error handler
}
void ScriptApiEntity::luaentity_Remove(u16 id)
//infostream<<"scriptapi_luaentity_get_staticdata: id="<<id<<std::endl;
+ int error_handler = PUSH_ERROR_HANDLER(L);
+
// Get core.luaentities[id]
luaentity_get(L, id);
int object = lua_gettop(L);
lua_pushvalue(L, object); // self
setOriginFromTable(object);
- PCALL_RES(lua_pcall(L, 1, 1, m_errorhandler));
+ PCALL_RES(lua_pcall(L, 1, 1, error_handler));
- lua_remove(L, object); // Remove object
+ lua_remove(L, object);
+ lua_remove(L, error_handler);
size_t len = 0;
const char *s = lua_tolstring(L, -1, &len);
//infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
+ int error_handler = PUSH_ERROR_HANDLER(L);
+
// Get core.luaentities[id]
luaentity_get(L, id);
int object = lua_gettop(L);
lua_pushnumber(L, dtime); // dtime
setOriginFromTable(object);
- PCALL_RES(lua_pcall(L, 2, 0, m_errorhandler));
+ PCALL_RES(lua_pcall(L, 2, 0, error_handler));
- lua_pop(L, 1); // Pop object
+ lua_pop(L, 2); // Pop object and error handler
}
// Calls entity:on_punch(ObjectRef puncher, time_from_last_punch,
//infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
+ int error_handler = PUSH_ERROR_HANDLER(L);
+
// Get core.luaentities[id]
luaentity_get(L,id);
int object = lua_gettop(L);
push_v3f(L, dir);
setOriginFromTable(object);
- PCALL_RES(lua_pcall(L, 5, 0, m_errorhandler));
+ PCALL_RES(lua_pcall(L, 5, 0, error_handler));
- lua_pop(L, 1); // Pop object
+ lua_pop(L, 2); // Pop object and error handler
}
// Calls entity:on_rightclick(ObjectRef clicker)
//infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
+ int error_handler = PUSH_ERROR_HANDLER(L);
+
// Get core.luaentities[id]
luaentity_get(L, id);
int object = lua_gettop(L);
objectrefGetOrCreate(L, clicker); // Clicker reference
setOriginFromTable(object);
- PCALL_RES(lua_pcall(L, 2, 0, m_errorhandler));
+ PCALL_RES(lua_pcall(L, 2, 0, error_handler));
- lua_pop(L, 1); // Pop object
+ lua_pop(L, 2); // Pop object and error handler
}
{
SCRIPTAPI_PRECHECKHEADER
+ int error_handler = PUSH_ERROR_HANDLER(L);
+
// Push callback function on stack
if (!getDetachedInventoryCallback(name, "allow_move"))
return count;
lua_pushinteger(L, to_index + 1); // to_index
lua_pushinteger(L, count); // count
objectrefGetOrCreate(L, player); // player
- PCALL_RES(lua_pcall(L, 7, 1, m_errorhandler));
+ PCALL_RES(lua_pcall(L, 7, 1, error_handler));
if(!lua_isnumber(L, -1))
throw LuaError("allow_move should return a number. name=" + name);
int ret = luaL_checkinteger(L, -1);
- lua_pop(L, 1); // Pop integer
+ lua_pop(L, 2); // Pop integer and error handler
return ret;
}
{
SCRIPTAPI_PRECHECKHEADER
+ int error_handler = PUSH_ERROR_HANDLER(L);
+
// Push callback function on stack
if (!getDetachedInventoryCallback(name, "allow_put"))
return stack.count; // All will be accepted
lua_pushinteger(L, index + 1); // index
LuaItemStack::create(L, stack); // stack
objectrefGetOrCreate(L, player); // player
- PCALL_RES(lua_pcall(L, 5, 1, m_errorhandler));
+ PCALL_RES(lua_pcall(L, 5, 1, error_handler));
if (!lua_isnumber(L, -1))
throw LuaError("allow_put should return a number. name=" + name);
int ret = luaL_checkinteger(L, -1);
- lua_pop(L, 1); // Pop integer
+ lua_pop(L, 2); // Pop integer and error handler
return ret;
}
{
SCRIPTAPI_PRECHECKHEADER
+ int error_handler = PUSH_ERROR_HANDLER(L);
+
// Push callback function on stack
if (!getDetachedInventoryCallback(name, "allow_take"))
return stack.count; // All will be accepted
lua_pushinteger(L, index + 1); // index
LuaItemStack::create(L, stack); // stack
objectrefGetOrCreate(L, player); // player
- PCALL_RES(lua_pcall(L, 5, 1, m_errorhandler));
+ PCALL_RES(lua_pcall(L, 5, 1, error_handler));
if (!lua_isnumber(L, -1))
throw LuaError("allow_take should return a number. name=" + name);
int ret = luaL_checkinteger(L, -1);
- lua_pop(L, 1); // Pop integer
+ lua_pop(L, 2); // Pop integer and error handler
return ret;
}
{
SCRIPTAPI_PRECHECKHEADER
+ int error_handler = PUSH_ERROR_HANDLER(L);
+
// Push callback function on stack
if (!getDetachedInventoryCallback(name, "on_move"))
return;
lua_pushinteger(L, to_index + 1); // to_index
lua_pushinteger(L, count); // count
objectrefGetOrCreate(L, player); // player
- PCALL_RES(lua_pcall(L, 7, 0, m_errorhandler));
+ PCALL_RES(lua_pcall(L, 7, 0, error_handler));
+ lua_pop(L, 1); // Pop error handler
}
// Report put items
{
SCRIPTAPI_PRECHECKHEADER
+ int error_handler = PUSH_ERROR_HANDLER(L);
+
// Push callback function on stack
if (!getDetachedInventoryCallback(name, "on_put"))
return;
lua_pushinteger(L, index + 1); // index
LuaItemStack::create(L, stack); // stack
objectrefGetOrCreate(L, player); // player
- PCALL_RES(lua_pcall(L, 5, 0, m_errorhandler));
+ PCALL_RES(lua_pcall(L, 5, 0, error_handler));
+ lua_pop(L, 1); // Pop error handler
}
// Report taken items
{
SCRIPTAPI_PRECHECKHEADER
+ int error_handler = PUSH_ERROR_HANDLER(L);
+
// Push callback function on stack
if (!getDetachedInventoryCallback(name, "on_take"))
return;
lua_pushinteger(L, index + 1); // index
LuaItemStack::create(L, stack); // stack
objectrefGetOrCreate(L, player); // player
- PCALL_RES(lua_pcall(L, 5, 0, m_errorhandler));
+ PCALL_RES(lua_pcall(L, 5, 0, error_handler));
+ lua_pop(L, 1); // Pop error handler
}
// Retrieves core.detached_inventories[name][callbackname]
{
SCRIPTAPI_PRECHECKHEADER
+ int error_handler = PUSH_ERROR_HANDLER(L);
+
// Push callback function on stack
if (!getItemCallback(item.name.c_str(), "on_drop"))
return false;
LuaItemStack::create(L, item);
objectrefGetOrCreate(L, dropper);
pushFloatPos(L, pos);
- PCALL_RES(lua_pcall(L, 3, 1, m_errorhandler));
+ PCALL_RES(lua_pcall(L, 3, 1, error_handler));
if (!lua_isnil(L, -1)) {
try {
item = read_item(L,-1, getServer());
throw LuaError(std::string(e.what()) + ". item=" + item.name);
}
}
- lua_pop(L, 1); // Pop item
+ lua_pop(L, 2); // Pop item and error handler
return true;
}
{
SCRIPTAPI_PRECHECKHEADER
+ int error_handler = PUSH_ERROR_HANDLER(L);
+
// Push callback function on stack
if (!getItemCallback(item.name.c_str(), "on_place"))
return false;
LuaItemStack::create(L, item);
objectrefGetOrCreate(L, placer);
pushPointedThing(pointed);
- PCALL_RES(lua_pcall(L, 3, 1, m_errorhandler));
+ PCALL_RES(lua_pcall(L, 3, 1, error_handler));
if (!lua_isnil(L, -1)) {
try {
item = read_item(L,-1, getServer());
throw LuaError(std::string(e.what()) + ". item=" + item.name);
}
}
- lua_pop(L, 1); // Pop item
+ lua_pop(L, 2); // Pop item and error handler
return true;
}
{
SCRIPTAPI_PRECHECKHEADER
+ int error_handler = PUSH_ERROR_HANDLER(L);
+
// Push callback function on stack
if (!getItemCallback(item.name.c_str(), "on_use"))
return false;
LuaItemStack::create(L, item);
objectrefGetOrCreate(L, user);
pushPointedThing(pointed);
- PCALL_RES(lua_pcall(L, 3, 1, m_errorhandler));
+ PCALL_RES(lua_pcall(L, 3, 1, error_handler));
if(!lua_isnil(L, -1)) {
try {
item = read_item(L,-1, getServer());
throw LuaError(std::string(e.what()) + ". item=" + item.name);
}
}
- lua_pop(L, 1); // Pop item
+ lua_pop(L, 2); // Pop item and error handler
return true;
}
{
SCRIPTAPI_PRECHECKHEADER
+ int error_handler = PUSH_ERROR_HANDLER(L);
+
lua_getglobal(L, "core");
lua_getfield(L, -1, "on_craft");
LuaItemStack::create(L, item);
push_items(L, items);
InvRef::create(L, craft_inv);
- PCALL_RES(lua_pcall(L, 4, 1, m_errorhandler));
+ PCALL_RES(lua_pcall(L, 4, 1, error_handler));
if (!lua_isnil(L, -1)) {
try {
item = read_item(L,-1, getServer());
throw LuaError(std::string(e.what()) + ". item=" + item.name);
}
}
- lua_pop(L, 1); // Pop item
+ lua_pop(L, 2); // Pop item and error handler
return true;
}
{
SCRIPTAPI_PRECHECKHEADER
+ int error_handler = PUSH_ERROR_HANDLER(L);
+
lua_getglobal(L, "core");
lua_getfield(L, -1, "craft_predict");
LuaItemStack::create(L, item);
push_items(L, items);
InvRef::create(L, craft_inv);
- PCALL_RES(lua_pcall(L, 4, 1, m_errorhandler));
+ PCALL_RES(lua_pcall(L, 4, 1, error_handler));
if (!lua_isnil(L, -1)) {
try {
item = read_item(L,-1, getServer());
throw LuaError(std::string(e.what()) + ". item=" + item.name);
}
}
- lua_pop(L, 1); // Pop item
+ lua_pop(L, 2); // Pop item and error handler
return true;
}
{
SCRIPTAPI_PRECHECKHEADER
+ int error_handler = PUSH_ERROR_HANDLER(L);
+
// Get handler function
lua_getglobal(L, "core");
lua_getfield(L, -1, "event_handler");
// Call it
lua_pushstring(L, text.c_str());
- PCALL_RES(lua_pcall(L, 1, 0, m_errorhandler));
+ PCALL_RES(lua_pcall(L, 1, 0, error_handler));
+ lua_pop(L, 1); // Pop error handler
}
void ScriptApiMainMenu::handleMainMenuButtons(const StringMap &fields)
{
SCRIPTAPI_PRECHECKHEADER
+ int error_handler = PUSH_ERROR_HANDLER(L);
+
// Get handler function
lua_getglobal(L, "core");
lua_getfield(L, -1, "button_handler");
}
// Call it
- PCALL_RES(lua_pcall(L, 1, 0, m_errorhandler));
+ PCALL_RES(lua_pcall(L, 1, 0, error_handler));
+ lua_pop(L, 1); // Pop error handler
}
{
SCRIPTAPI_PRECHECKHEADER
+ int error_handler = PUSH_ERROR_HANDLER(L);
+
INodeDefManager *ndef = getServer()->ndef();
// Push callback function on stack
pushnode(L, node, ndef);
objectrefGetOrCreate(L, puncher);
pushPointedThing(pointed);
- PCALL_RES(lua_pcall(L, 4, 0, m_errorhandler));
+ PCALL_RES(lua_pcall(L, 4, 0, error_handler));
+ lua_pop(L, 1); // Pop error handler
return true;
}
{
SCRIPTAPI_PRECHECKHEADER
+ int error_handler = PUSH_ERROR_HANDLER(L);
+
INodeDefManager *ndef = getServer()->ndef();
// Push callback function on stack
push_v3s16(L, p);
pushnode(L, node, ndef);
objectrefGetOrCreate(L, digger);
- PCALL_RES(lua_pcall(L, 3, 0, m_errorhandler));
+ PCALL_RES(lua_pcall(L, 3, 0, error_handler));
+ lua_pop(L, 1); // Pop error handler
return true;
}
{
SCRIPTAPI_PRECHECKHEADER
+ int error_handler = PUSH_ERROR_HANDLER(L);
+
INodeDefManager *ndef = getServer()->ndef();
// Push callback function on stack
// Call function
push_v3s16(L, p);
- PCALL_RES(lua_pcall(L, 1, 0, m_errorhandler));
+ PCALL_RES(lua_pcall(L, 1, 0, error_handler));
+ lua_pop(L, 1); // Pop error handler
}
void ScriptApiNode::node_on_destruct(v3s16 p, MapNode node)
{
SCRIPTAPI_PRECHECKHEADER
+ int error_handler = PUSH_ERROR_HANDLER(L);
+
INodeDefManager *ndef = getServer()->ndef();
// Push callback function on stack
// Call function
push_v3s16(L, p);
- PCALL_RES(lua_pcall(L, 1, 0, m_errorhandler));
+ PCALL_RES(lua_pcall(L, 1, 0, error_handler));
+ lua_pop(L, 1); // Pop error handler
}
void ScriptApiNode::node_after_destruct(v3s16 p, MapNode node)
{
SCRIPTAPI_PRECHECKHEADER
+ int error_handler = PUSH_ERROR_HANDLER(L);
+
INodeDefManager *ndef = getServer()->ndef();
// Push callback function on stack
// Call function
push_v3s16(L, p);
pushnode(L, node, ndef);
- PCALL_RES(lua_pcall(L, 2, 0, m_errorhandler));
+ PCALL_RES(lua_pcall(L, 2, 0, error_handler));
+ lua_pop(L, 1); // Pop error handler
}
bool ScriptApiNode::node_on_timer(v3s16 p, MapNode node, f32 dtime)
{
SCRIPTAPI_PRECHECKHEADER
+ int error_handler = PUSH_ERROR_HANDLER(L);
+
INodeDefManager *ndef = getServer()->ndef();
// Push callback function on stack
// Call function
push_v3s16(L, p);
lua_pushnumber(L,dtime);
- PCALL_RES(lua_pcall(L, 2, 1, m_errorhandler));
+ PCALL_RES(lua_pcall(L, 2, 1, error_handler));
+ lua_remove(L, error_handler);
return (bool) lua_isboolean(L, -1) && (bool) lua_toboolean(L, -1) == true;
}
{
SCRIPTAPI_PRECHECKHEADER
+ int error_handler = PUSH_ERROR_HANDLER(L);
+
INodeDefManager *ndef = getServer()->ndef();
// If node doesn't exist, we don't know what callback to call
lua_settable(L, -3);
}
objectrefGetOrCreate(L, sender); // player
- PCALL_RES(lua_pcall(L, 4, 0, m_errorhandler));
+ PCALL_RES(lua_pcall(L, 4, 0, error_handler));
+ lua_pop(L, 1); // Pop error handler
}
void ScriptApiNode::node_falling_update(v3s16 p)
{
SCRIPTAPI_PRECHECKHEADER
+ int error_handler = PUSH_ERROR_HANDLER(L);
+
lua_getglobal(L, "nodeupdate");
push_v3s16(L, p);
- PCALL_RES(lua_pcall(L, 1, 0, m_errorhandler));
+ PCALL_RES(lua_pcall(L, 1, 0, error_handler));
+ lua_pop(L, 1); // Pop error handler
}
void ScriptApiNode::node_falling_update_single(v3s16 p)
{
SCRIPTAPI_PRECHECKHEADER
+ int error_handler = PUSH_ERROR_HANDLER(L);
+
lua_getglobal(L, "nodeupdate_single");
push_v3s16(L, p);
- PCALL_RES(lua_pcall(L, 1, 0, m_errorhandler));
+ PCALL_RES(lua_pcall(L, 1, 0, error_handler));
+ lua_pop(L, 1); // Pop error handler
}
{
SCRIPTAPI_PRECHECKHEADER
+ int error_handler = PUSH_ERROR_HANDLER(L);
+
INodeDefManager *ndef = getServer()->ndef();
// If node doesn't exist, we don't know what callback to call
lua_pushinteger(L, to_index + 1); // to_index
lua_pushinteger(L, count); // count
objectrefGetOrCreate(L, player); // player
- PCALL_RES(lua_pcall(L, 7, 1, m_errorhandler));
+ PCALL_RES(lua_pcall(L, 7, 1, error_handler));
if (!lua_isnumber(L, -1))
throw LuaError("allow_metadata_inventory_move should"
" return a number, guilty node: " + nodename);
int num = luaL_checkinteger(L, -1);
- lua_pop(L, 1); // Pop integer
+ lua_pop(L, 2); // Pop integer and error handler
return num;
}
{
SCRIPTAPI_PRECHECKHEADER
+ int error_handler = PUSH_ERROR_HANDLER(L);
+
INodeDefManager *ndef = getServer()->ndef();
// If node doesn't exist, we don't know what callback to call
lua_pushinteger(L, index + 1); // index
LuaItemStack::create(L, stack); // stack
objectrefGetOrCreate(L, player); // player
- PCALL_RES(lua_pcall(L, 5, 1, m_errorhandler));
+ PCALL_RES(lua_pcall(L, 5, 1, error_handler));
if(!lua_isnumber(L, -1))
throw LuaError("allow_metadata_inventory_put should"
" return a number, guilty node: " + nodename);
int num = luaL_checkinteger(L, -1);
- lua_pop(L, 1); // Pop integer
+ lua_pop(L, 2); // Pop integer and error handler
return num;
}
{
SCRIPTAPI_PRECHECKHEADER
+ int error_handler = PUSH_ERROR_HANDLER(L);
+
INodeDefManager *ndef = getServer()->ndef();
// If node doesn't exist, we don't know what callback to call
lua_pushinteger(L, index + 1); // index
LuaItemStack::create(L, stack); // stack
objectrefGetOrCreate(L, player); // player
- PCALL_RES(lua_pcall(L, 5, 1, m_errorhandler));
+ PCALL_RES(lua_pcall(L, 5, 1, error_handler));
if (!lua_isnumber(L, -1))
throw LuaError("allow_metadata_inventory_take should"
" return a number, guilty node: " + nodename);
int num = luaL_checkinteger(L, -1);
- lua_pop(L, 1); // Pop integer
+ lua_pop(L, 2); // Pop integer and error handler
return num;
}
{
SCRIPTAPI_PRECHECKHEADER
+ int error_handler = PUSH_ERROR_HANDLER(L);
+
INodeDefManager *ndef = getServer()->ndef();
// If node doesn't exist, we don't know what callback to call
lua_pushinteger(L, to_index + 1); // to_index
lua_pushinteger(L, count); // count
objectrefGetOrCreate(L, player); // player
- PCALL_RES(lua_pcall(L, 7, 0, m_errorhandler));
+ PCALL_RES(lua_pcall(L, 7, 0, error_handler));
+ lua_pop(L, 1); // Pop error handler
}
// Report put items
{
SCRIPTAPI_PRECHECKHEADER
+ int error_handler = PUSH_ERROR_HANDLER(L);
+
INodeDefManager *ndef = getServer()->ndef();
// If node doesn't exist, we don't know what callback to call
lua_pushinteger(L, index + 1); // index
LuaItemStack::create(L, stack); // stack
objectrefGetOrCreate(L, player); // player
- PCALL_RES(lua_pcall(L, 5, 0, m_errorhandler));
+ PCALL_RES(lua_pcall(L, 5, 0, error_handler));
+ lua_pop(L, 1); // Pop error handler
}
// Report taken items
{
SCRIPTAPI_PRECHECKHEADER
+ int error_handler = PUSH_ERROR_HANDLER(L);
+
INodeDefManager *ndef = getServer()->ndef();
// If node doesn't exist, we don't know what callback to call
lua_pushinteger(L, index + 1); // index
LuaItemStack::create(L, stack); // stack
objectrefGetOrCreate(L, player); // player
- PCALL_RES(lua_pcall(L, 5, 0, m_errorhandler));
+ PCALL_RES(lua_pcall(L, 5, 0, error_handler));
+ lua_pop(L, 1); // Pop error handler
}
ScriptApiNodemeta::ScriptApiNodemeta()
{
SCRIPTAPI_PRECHECKHEADER
+ int error_handler = PUSH_ERROR_HANDLER(L);
+
// Get core.registered_on_player_hpchange
lua_getglobal(L, "core");
lua_getfield(L, -1, "registered_on_player_hpchange");
objectrefGetOrCreate(L, player);
lua_pushnumber(L, hp_change);
- PCALL_RES(lua_pcall(L, 2, 1, m_errorhandler));
+ PCALL_RES(lua_pcall(L, 2, 1, error_handler));
hp_change = lua_tointeger(L, -1);
- lua_pop(L, -1);
+ lua_pop(L, 2); // Pop result and error handler
return hp_change;
}
{
SCRIPTAPI_PRECHECKHEADER
+ int error_handler = PUSH_ERROR_HANDLER(L);
getAuthHandler();
lua_getfield(L, -1, "get_auth");
if (lua_type(L, -1) != LUA_TFUNCTION)
throw LuaError("Authentication handler missing get_auth");
lua_pushstring(L, playername.c_str());
- PCALL_RES(lua_pcall(L, 1, 1, m_errorhandler));
+ PCALL_RES(lua_pcall(L, 1, 1, error_handler));
lua_remove(L, -2); // Remove auth handler
+ lua_remove(L, error_handler);
// nil = login not allowed
if (lua_isnil(L, -1))
{
SCRIPTAPI_PRECHECKHEADER
+ int error_handler = PUSH_ERROR_HANDLER(L);
getAuthHandler();
lua_getfield(L, -1, "create_auth");
lua_remove(L, -2); // Remove auth handler
throw LuaError("Authentication handler missing create_auth");
lua_pushstring(L, playername.c_str());
lua_pushstring(L, password.c_str());
- PCALL_RES(lua_pcall(L, 2, 0, m_errorhandler));
+ PCALL_RES(lua_pcall(L, 2, 0, error_handler));
+ lua_pop(L, 1); // Pop error handler
}
bool ScriptApiServer::setPassword(const std::string &playername,
{
SCRIPTAPI_PRECHECKHEADER
+ int error_handler = PUSH_ERROR_HANDLER(L);
getAuthHandler();
lua_getfield(L, -1, "set_password");
lua_remove(L, -2); // Remove auth handler
throw LuaError("Authentication handler missing set_password");
lua_pushstring(L, playername.c_str());
lua_pushstring(L, password.c_str());
- PCALL_RES(lua_pcall(L, 2, 1, m_errorhandler));
+ PCALL_RES(lua_pcall(L, 2, 1, error_handler));
+ lua_remove(L, error_handler);
return lua_toboolean(L, -1);
}
sanity_check(lua_checkstack(L, 20));
StackUnroller stack_unroller(L);
- lua_pushcfunction(L, script_error_handler);
- int errorhandler = lua_gettop(L);
+ int error_handler = PUSH_ERROR_HANDLER(L);
// Get registered_abms
lua_getglobal(L, "core");
lua_pushnumber(L, active_object_count);
lua_pushnumber(L, active_object_count_wider);
- int result = lua_pcall(L, 4, 0, errorhandler);
+ int result = lua_pcall(L, 4, 0, error_handler);
if (result)
scriptIface->scriptError(result, "LuaABM::trigger");
if(item.empty() || !item.isKnown(getServer(L)->idef()))
return 0;
- lua_pushcfunction(L, script_error_handler);
- int errorhandler = lua_gettop(L);
+ int error_handler = PUSH_ERROR_HANDLER(L);
// Use spawn_item to spawn a __builtin:item
lua_getglobal(L, "core");
lua_pushvalue(L, 1);
lua_pushstring(L, item.getItemString().c_str());
- PCALL_RESL(L, lua_pcall(L, 2, 1, errorhandler));
+ PCALL_RESL(L, lua_pcall(L, 2, 1, error_handler));
- lua_remove(L, errorhandler); // Remove error handler
+ lua_remove(L, error_handler);
return 1;
}
/******************************************************************************/
void MainMenuScripting::step() {
- asyncEngine.step(getStack(), m_errorhandler);
+ asyncEngine.step(getStack());
}
/******************************************************************************/