diff options
author | ShadowNinja <shadowninja@minetest.net> | 2013-11-05 12:06:15 -0500 |
---|---|---|
committer | ShadowNinja <shadowninja@minetest.net> | 2013-11-15 14:13:31 -0500 |
commit | 371b39a09a0bf248d674fae718f5ff369e895b66 (patch) | |
tree | da8bb27e27a9c89eac895d211721de11a3781533 /src/script/cpp_api | |
parent | 3f519eb72922607329e1e6a48768d84d1f443efc (diff) | |
download | minetest-371b39a09a0bf248d674fae718f5ff369e895b66.tar.gz minetest-371b39a09a0bf248d674fae718f5ff369e895b66.tar.bz2 minetest-371b39a09a0bf248d674fae718f5ff369e895b66.zip |
Pass a errfunc to lua_pcall to get a traceback
Diffstat (limited to 'src/script/cpp_api')
-rw-r--r-- | src/script/cpp_api/s_base.cpp | 33 | ||||
-rw-r--r-- | src/script/cpp_api/s_base.h | 3 | ||||
-rw-r--r-- | src/script/cpp_api/s_entity.cpp | 60 | ||||
-rw-r--r-- | src/script/cpp_api/s_inventory.cpp | 147 | ||||
-rw-r--r-- | src/script/cpp_api/s_item.cpp | 70 | ||||
-rw-r--r-- | src/script/cpp_api/s_mainmenu.cpp | 28 | ||||
-rw-r--r-- | src/script/cpp_api/s_node.cpp | 92 | ||||
-rw-r--r-- | src/script/cpp_api/s_nodemeta.cpp | 162 | ||||
-rw-r--r-- | src/script/cpp_api/s_server.cpp | 31 |
9 files changed, 345 insertions, 281 deletions
diff --git a/src/script/cpp_api/s_base.cpp b/src/script/cpp_api/s_base.cpp index e26d54ba7..b1272b64e 100644 --- a/src/script/cpp_api/s_base.cpp +++ b/src/script/cpp_api/s_base.cpp @@ -55,23 +55,6 @@ public: } }; -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; -} - /* ScriptApiBase @@ -133,7 +116,7 @@ bool ScriptApiBase::loadScript(const std::string &scriptpath) lua_State *L = getStack(); - lua_pushcfunction(L, loadScript_ErrorHandler); + lua_pushcfunction(L, script_error_handler); int errorhandler = lua_gettop(L); int ret = luaL_loadfile(L, scriptpath.c_str()) || lua_pcall(L, 0, 0, errorhandler); @@ -144,7 +127,7 @@ bool ScriptApiBase::loadScript(const std::string &scriptpath) errorstream<<std::endl; errorstream<<lua_tostring(L, -1)<<std::endl; errorstream<<std::endl; - errorstream<<"=======END OF ERROR FROM LUA ========"<<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; @@ -159,19 +142,13 @@ void ScriptApiBase::realityCheck() if(top >= 30){ dstream<<"Stack is over 30:"<<std::endl; stackDump(dstream); - scriptError("Stack is over 30 (reality check)"); + throw LuaError(m_luastack, "Stack is over 30 (reality check)"); } } -void ScriptApiBase::scriptError(const char *fmt, ...) +void ScriptApiBase::scriptError() { - va_list argp; - va_start(argp, fmt); - char buf[10000]; - vsnprintf(buf, 10000, fmt, argp); - va_end(argp); - //errorstream<<"SCRIPT ERROR: "<<buf; - throw LuaError(m_luastack, buf); + throw LuaError(NULL, lua_tostring(m_luastack, -1)); } void ScriptApiBase::stackDump(std::ostream &o) diff --git a/src/script/cpp_api/s_base.h b/src/script/cpp_api/s_base.h index 63f7e423f..75552cc34 100644 --- a/src/script/cpp_api/s_base.h +++ b/src/script/cpp_api/s_base.h @@ -31,6 +31,7 @@ extern "C" { #include "jthread/jmutex.h" #include "jthread/jmutexautolock.h" #include "common/c_types.h" +#include "common/c_internal.h" #define SCRIPTAPI_LOCK_DEBUG @@ -65,7 +66,7 @@ protected: { return m_luastack; } void realityCheck(); - void scriptError(const char *fmt, ...); + void scriptError(); void stackDump(std::ostream &o); Server* getServer() { return m_server; } diff --git a/src/script/cpp_api/s_entity.cpp b/src/script/cpp_api/s_entity.cpp index cefa27cb1..c9d1bd8e0 100644 --- a/src/script/cpp_api/s_entity.cpp +++ b/src/script/cpp_api/s_entity.cpp @@ -78,25 +78,29 @@ void ScriptApiEntity::luaentity_Activate(u16 id, { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + verbosestream<<"scriptapi_luaentity_activate: id="<<id<<std::endl; // Get minetest.luaentities[id] - luaentity_get(L,id); + luaentity_get(L, id); int object = lua_gettop(L); // Get on_activate function - lua_pushvalue(L, object); lua_getfield(L, -1, "on_activate"); - if(!lua_isnil(L, -1)){ + if(!lua_isnil(L, -1)) { luaL_checktype(L, -1, LUA_TFUNCTION); lua_pushvalue(L, object); // self lua_pushlstring(L, staticdata.c_str(), staticdata.size()); lua_pushinteger(L, dtime_s); // Call with 3 arguments, 0 results - if(lua_pcall(L, 3, 0, 0)) - scriptError("error running function on_activate: %s\n", - lua_tostring(L, -1)); + if(lua_pcall(L, 3, 0, errorhandler)) + scriptError(); + } else { + lua_pop(L, 1); } + lua_pop(L, 2); // Pop object and error handler } void ScriptApiEntity::luaentity_Remove(u16 id) @@ -123,14 +127,16 @@ std::string ScriptApiEntity::luaentity_GetStaticdata(u16 id) { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + //infostream<<"scriptapi_luaentity_get_staticdata: id="<<id<<std::endl; // Get minetest.luaentities[id] - luaentity_get(L,id); + luaentity_get(L, id); int object = lua_gettop(L); // Get get_staticdata function - lua_pushvalue(L, object); lua_getfield(L, -1, "get_staticdata"); if(lua_isnil(L, -1)) return ""; @@ -138,11 +144,12 @@ std::string ScriptApiEntity::luaentity_GetStaticdata(u16 id) luaL_checktype(L, -1, LUA_TFUNCTION); lua_pushvalue(L, object); // self // Call with 1 arguments, 1 results - if(lua_pcall(L, 1, 1, 0)) - scriptError("error running function get_staticdata: %s\n", - lua_tostring(L, -1)); + if(lua_pcall(L, 1, 1, errorhandler)) + scriptError(); + lua_remove(L, object); // Remove object + lua_remove(L, errorhandler); // Remove error handler - size_t len=0; + size_t len = 0; const char *s = lua_tolstring(L, -1, &len); return std::string(s, len); } @@ -192,10 +199,13 @@ void ScriptApiEntity::luaentity_Step(u16 id, float dtime) { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl; // Get minetest.luaentities[id] - luaentity_get(L,id); + luaentity_get(L, id); int object = lua_gettop(L); // State: object is at top of stack // Get step function @@ -206,8 +216,10 @@ void ScriptApiEntity::luaentity_Step(u16 id, float dtime) lua_pushvalue(L, object); // self lua_pushnumber(L, dtime); // dtime // Call with 2 arguments, 0 results - if(lua_pcall(L, 2, 0, 0)) - scriptError("error running function 'on_step': %s\n", lua_tostring(L, -1)); + if(lua_pcall(L, 2, 0, errorhandler)) + scriptError(); + lua_remove(L, object); // Remove object + lua_remove(L, errorhandler); // Remove error handler } // Calls entity:on_punch(ObjectRef puncher, time_from_last_punch, @@ -218,6 +230,9 @@ void ScriptApiEntity::luaentity_Punch(u16 id, { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl; // Get minetest.luaentities[id] @@ -235,8 +250,10 @@ void ScriptApiEntity::luaentity_Punch(u16 id, push_tool_capabilities(L, *toolcap); push_v3f(L, dir); // Call with 5 arguments, 0 results - if(lua_pcall(L, 5, 0, 0)) - scriptError("error running function 'on_punch': %s\n", lua_tostring(L, -1)); + if(lua_pcall(L, 5, 0, errorhandler)) + scriptError(); + lua_remove(L, object); // Remove object + lua_remove(L, errorhandler); // Remove error handler } // Calls entity:on_rightclick(ObjectRef clicker) @@ -245,6 +262,9 @@ void ScriptApiEntity::luaentity_Rightclick(u16 id, { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl; // Get minetest.luaentities[id] @@ -259,7 +279,9 @@ void ScriptApiEntity::luaentity_Rightclick(u16 id, lua_pushvalue(L, object); // self objectrefGetOrCreate(clicker); // Clicker reference // Call with 2 arguments, 0 results - if(lua_pcall(L, 2, 0, 0)) - scriptError("error running function 'on_rightclick': %s\n", lua_tostring(L, -1)); + if(lua_pcall(L, 2, 0, errorhandler)) + scriptError(); + lua_remove(L, object); // Remove object + lua_remove(L, errorhandler); // Remove error handler } diff --git a/src/script/cpp_api/s_inventory.cpp b/src/script/cpp_api/s_inventory.cpp index 09f26d80c..4ee6e4be0 100644 --- a/src/script/cpp_api/s_inventory.cpp +++ b/src/script/cpp_api/s_inventory.cpp @@ -33,6 +33,9 @@ int ScriptApiDetached::detached_inventory_AllowMove( { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + // Push callback function on stack if(!getDetachedInventoryCallback(name, "allow_move")) return count; @@ -42,23 +45,19 @@ int ScriptApiDetached::detached_inventory_AllowMove( InventoryLocation loc; loc.setDetached(name); InvRef::create(L, loc); - // from_list - lua_pushstring(L, from_list.c_str()); - // from_index - lua_pushinteger(L, from_index + 1); - // to_list - lua_pushstring(L, to_list.c_str()); - // to_index - lua_pushinteger(L, to_index + 1); - // count - lua_pushinteger(L, count); - // player - objectrefGetOrCreate(player); - if(lua_pcall(L, 7, 1, 0)) - scriptError("error: %s", lua_tostring(L, -1)); + lua_pushstring(L, from_list.c_str()); // from_list + lua_pushinteger(L, from_index + 1); // from_index + lua_pushstring(L, to_list.c_str()); // to_list + lua_pushinteger(L, to_index + 1); // to_index + lua_pushinteger(L, count); // count + objectrefGetOrCreate(player); // player + if(lua_pcall(L, 7, 1, errorhandler)) + scriptError(); if(!lua_isnumber(L, -1)) throw LuaError(L, "allow_move should return a number"); - return luaL_checkinteger(L, -1); + int ret = luaL_checkinteger(L, -1); + lua_pop(L, 2); // Pop integer and error handler + return ret; } // Return number of accepted items to be put @@ -69,28 +68,28 @@ int ScriptApiDetached::detached_inventory_AllowPut( { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + // Push callback function on stack if(!getDetachedInventoryCallback(name, "allow_put")) return stack.count; // All will be accepted // Call function(inv, listname, index, stack, player) - // inv InventoryLocation loc; loc.setDetached(name); - InvRef::create(L, loc); - // listname - lua_pushstring(L, listname.c_str()); - // index - lua_pushinteger(L, index + 1); - // stack - LuaItemStack::create(L, stack); - // player - objectrefGetOrCreate(player); - if(lua_pcall(L, 5, 1, 0)) - scriptError("error: %s", lua_tostring(L, -1)); + InvRef::create(L, loc); // inv + lua_pushstring(L, listname.c_str()); // listname + lua_pushinteger(L, index + 1); // index + LuaItemStack::create(L, stack); // stack + objectrefGetOrCreate(player); // player + if(lua_pcall(L, 5, 1, errorhandler)) + scriptError(); if(!lua_isnumber(L, -1)) throw LuaError(L, "allow_put should return a number"); - return luaL_checkinteger(L, -1); + int ret = luaL_checkinteger(L, -1); + lua_pop(L, 2); // Pop integer and error handler + return ret; } // Return number of accepted items to be taken @@ -101,28 +100,28 @@ int ScriptApiDetached::detached_inventory_AllowTake( { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + // Push callback function on stack if(!getDetachedInventoryCallback(name, "allow_take")) return stack.count; // All will be accepted // Call function(inv, listname, index, stack, player) - // inv InventoryLocation loc; loc.setDetached(name); - InvRef::create(L, loc); - // listname - lua_pushstring(L, listname.c_str()); - // index - lua_pushinteger(L, index + 1); - // stack - LuaItemStack::create(L, stack); - // player - objectrefGetOrCreate(player); - if(lua_pcall(L, 5, 1, 0)) - scriptError("error: %s", lua_tostring(L, -1)); + InvRef::create(L, loc); // inv + lua_pushstring(L, listname.c_str()); // listname + lua_pushinteger(L, index + 1); // index + LuaItemStack::create(L, stack); // stack + objectrefGetOrCreate(player); // player + if(lua_pcall(L, 5, 1, errorhandler)) + scriptError(); if(!lua_isnumber(L, -1)) throw LuaError(L, "allow_take should return a number"); - return luaL_checkinteger(L, -1); + int ret = luaL_checkinteger(L, -1); + lua_pop(L, 2); // Pop integer and error handler + return ret; } // Report moved items @@ -134,6 +133,9 @@ void ScriptApiDetached::detached_inventory_OnMove( { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + // Push callback function on stack if(!getDetachedInventoryCallback(name, "on_move")) return; @@ -143,20 +145,15 @@ void ScriptApiDetached::detached_inventory_OnMove( InventoryLocation loc; loc.setDetached(name); InvRef::create(L, loc); - // from_list - lua_pushstring(L, from_list.c_str()); - // from_index - lua_pushinteger(L, from_index + 1); - // to_list - lua_pushstring(L, to_list.c_str()); - // to_index - lua_pushinteger(L, to_index + 1); - // count - lua_pushinteger(L, count); - // player - objectrefGetOrCreate(player); - if(lua_pcall(L, 7, 0, 0)) - scriptError("error: %s", lua_tostring(L, -1)); + lua_pushstring(L, from_list.c_str()); // from_list + lua_pushinteger(L, from_index + 1); // from_index + lua_pushstring(L, to_list.c_str()); // to_list + lua_pushinteger(L, to_index + 1); // to_index + lua_pushinteger(L, count); // count + objectrefGetOrCreate(player); // player + if(lua_pcall(L, 7, 0, errorhandler)) + scriptError(); + lua_pop(L, 1); // Pop error handler } // Report put items @@ -167,6 +164,9 @@ void ScriptApiDetached::detached_inventory_OnPut( { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + // Push callback function on stack if(!getDetachedInventoryCallback(name, "on_put")) return; @@ -176,16 +176,13 @@ void ScriptApiDetached::detached_inventory_OnPut( InventoryLocation loc; loc.setDetached(name); InvRef::create(L, loc); - // listname - lua_pushstring(L, listname.c_str()); - // index - lua_pushinteger(L, index + 1); - // stack - LuaItemStack::create(L, stack); - // player - objectrefGetOrCreate(player); - if(lua_pcall(L, 5, 0, 0)) - scriptError("error: %s", lua_tostring(L, -1)); + lua_pushstring(L, listname.c_str()); // listname + lua_pushinteger(L, index + 1); // index + LuaItemStack::create(L, stack); // stack + objectrefGetOrCreate(player); // player + if(lua_pcall(L, 5, 0, errorhandler)) + scriptError(); + lua_pop(L, 1); // Pop error handler } // Report taken items @@ -196,6 +193,9 @@ void ScriptApiDetached::detached_inventory_OnTake( { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + // Push callback function on stack if(!getDetachedInventoryCallback(name, "on_take")) return; @@ -205,16 +205,13 @@ void ScriptApiDetached::detached_inventory_OnTake( InventoryLocation loc; loc.setDetached(name); InvRef::create(L, loc); - // listname - lua_pushstring(L, listname.c_str()); - // index - lua_pushinteger(L, index + 1); - // stack - LuaItemStack::create(L, stack); - // player - objectrefGetOrCreate(player); - if(lua_pcall(L, 5, 0, 0)) - scriptError("error: %s", lua_tostring(L, -1)); + lua_pushstring(L, listname.c_str()); // listname + lua_pushinteger(L, index + 1); // index + LuaItemStack::create(L, stack); // stack + objectrefGetOrCreate(player); // player + if(lua_pcall(L, 5, 0, errorhandler)) + scriptError(); + lua_pop(L, 1); // Pop error handler } // Retrieves minetest.detached_inventories[name][callbackname] diff --git a/src/script/cpp_api/s_item.cpp b/src/script/cpp_api/s_item.cpp index 1d5f218cf..49729e57b 100644 --- a/src/script/cpp_api/s_item.cpp +++ b/src/script/cpp_api/s_item.cpp @@ -34,6 +34,9 @@ bool ScriptApiItem::item_OnDrop(ItemStack &item, { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + // Push callback function on stack if(!getItemCallback(item.name.c_str(), "on_drop")) return false; @@ -42,10 +45,11 @@ bool ScriptApiItem::item_OnDrop(ItemStack &item, LuaItemStack::create(L, item); objectrefGetOrCreate(dropper); pushFloatPos(L, pos); - if(lua_pcall(L, 3, 1, 0)) - scriptError("error: %s", lua_tostring(L, -1)); + if(lua_pcall(L, 3, 1, errorhandler)) + scriptError(); if(!lua_isnil(L, -1)) item = read_item(L,-1, getServer()); + lua_pop(L, 2); // Pop item and error handler return true; } @@ -54,6 +58,9 @@ bool ScriptApiItem::item_OnPlace(ItemStack &item, { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + // Push callback function on stack if(!getItemCallback(item.name.c_str(), "on_place")) return false; @@ -62,10 +69,11 @@ bool ScriptApiItem::item_OnPlace(ItemStack &item, LuaItemStack::create(L, item); objectrefGetOrCreate(placer); pushPointedThing(pointed); - if(lua_pcall(L, 3, 1, 0)) - scriptError("error: %s", lua_tostring(L, -1)); + if(lua_pcall(L, 3, 1, errorhandler)) + scriptError(); if(!lua_isnil(L, -1)) item = read_item(L,-1, getServer()); + lua_pop(L, 2); // Pop item and error handler return true; } @@ -74,6 +82,9 @@ bool ScriptApiItem::item_OnUse(ItemStack &item, { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + // Push callback function on stack if(!getItemCallback(item.name.c_str(), "on_use")) return false; @@ -82,10 +93,11 @@ bool ScriptApiItem::item_OnUse(ItemStack &item, LuaItemStack::create(L, item); objectrefGetOrCreate(user); pushPointedThing(pointed); - if(lua_pcall(L, 3, 1, 0)) - scriptError("error: %s", lua_tostring(L, -1)); + if(lua_pcall(L, 3, 1, errorhandler)) + scriptError(); if(!lua_isnil(L, -1)) item = read_item(L,-1, getServer()); + lua_pop(L, 2); // Pop item and error handler return true; } @@ -94,6 +106,9 @@ bool ScriptApiItem::item_OnCraft(ItemStack &item, ServerActiveObject *user, { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + lua_getglobal(L, "minetest"); lua_getfield(L, -1, "on_craft"); LuaItemStack::create(L, item); @@ -106,10 +121,11 @@ bool ScriptApiItem::item_OnCraft(ItemStack &item, ServerActiveObject *user, push_items(L, items); InvRef::create(L, craft_inv); - if(lua_pcall(L, 4, 1, 0)) - scriptError("error: %s", lua_tostring(L, -1)); + if(lua_pcall(L, 4, 1, errorhandler)) + scriptError(); if(!lua_isnil(L, -1)) item = read_item(L,-1, getServer()); + lua_pop(L, 2); // Pop item and error handler return true; } @@ -118,11 +134,14 @@ bool ScriptApiItem::item_CraftPredict(ItemStack &item, ServerActiveObject *user, { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + lua_getglobal(L, "minetest"); lua_getfield(L, -1, "craft_predict"); LuaItemStack::create(L, item); objectrefGetOrCreate(user); - + //Push inventory list std::vector<ItemStack> items; for(u32 i=0; i<old_craft_grid->getSize(); i++) @@ -130,10 +149,11 @@ bool ScriptApiItem::item_CraftPredict(ItemStack &item, ServerActiveObject *user, push_items(L, items); InvRef::create(L, craft_inv); - if(lua_pcall(L, 4, 1, 0)) - scriptError("error: %s", lua_tostring(L, -1)); + if(lua_pcall(L, 4, 1, errorhandler)) + scriptError(); if(!lua_isnil(L, -1)) item = read_item(L,-1, getServer()); + lua_pop(L, 2); // Pop item and error handler return true; } @@ -149,15 +169,15 @@ bool ScriptApiItem::getItemCallback(const char *name, const char *callbackname) lua_getglobal(L, "minetest"); lua_getfield(L, -1, "registered_items"); - lua_remove(L, -2); + lua_remove(L, -2); // Remove minetest luaL_checktype(L, -1, LUA_TTABLE); lua_getfield(L, -1, name); - lua_remove(L, -2); + lua_remove(L, -2); // Remove registered_items // Should be a table if(lua_type(L, -1) != LUA_TTABLE) { // Report error and clean up - errorstream<<"Item \""<<name<<"\" not defined"<<std::endl; + errorstream << "Item \"" << name << "\" not defined" << std::endl; lua_pop(L, 1); // Try minetest.nodedef_default instead @@ -167,24 +187,16 @@ bool ScriptApiItem::getItemCallback(const char *name, const char *callbackname) luaL_checktype(L, -1, LUA_TTABLE); } lua_getfield(L, -1, callbackname); - lua_remove(L, -2); + lua_remove(L, -2); // Remove item def // Should be a function or nil - if(lua_type(L, -1) == LUA_TFUNCTION) - { + if (lua_type(L, -1) == LUA_TFUNCTION) { return true; + } else if (!lua_isnil(L, -1)) { + errorstream << "Item \"" << name << "\" callback \"" + << callbackname << "\" is not a function" << std::endl; } - else if(lua_isnil(L, -1)) - { - lua_pop(L, 1); - return false; - } - else - { - errorstream<<"Item \""<<name<<"\" callback \"" - <<callbackname<<" is not a function"<<std::endl; - lua_pop(L, 1); - return false; - } + lua_pop(L, 1); + return false; } void ScriptApiItem::pushPointedThing(const PointedThing& pointed) diff --git a/src/script/cpp_api/s_mainmenu.cpp b/src/script/cpp_api/s_mainmenu.cpp index af92c59a9..5c54f7368 100644 --- a/src/script/cpp_api/s_mainmenu.cpp +++ b/src/script/cpp_api/s_mainmenu.cpp @@ -37,29 +37,41 @@ void ScriptApiMainMenu::handleMainMenuEvent(std::string text) { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + // Get handler function lua_getglobal(L, "engine"); lua_getfield(L, -1, "event_handler"); - if(lua_isnil(L, -1)) + lua_remove(L, -2); // Remove engine + if(lua_isnil(L, -1)) { + lua_pop(L, 1); // Pop event_handler 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)); + if(lua_pcall(L, 1, 0, errorhandler)) + scriptError(); + lua_pop(L, 1); // Pop error handler } void ScriptApiMainMenu::handleMainMenuButtons(std::map<std::string, std::string> fields) { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + // Get handler function lua_getglobal(L, "engine"); lua_getfield(L, -1, "button_handler"); - if(lua_isnil(L, -1)) + lua_remove(L, -2); // Remove engine + if(lua_isnil(L, -1)) { + lua_pop(L, 1); // Pop button handler return; + } luaL_checktype(L, -1, LUA_TFUNCTION); // Convert fields to lua table @@ -74,7 +86,7 @@ void ScriptApiMainMenu::handleMainMenuButtons(std::map<std::string, std::string> } // Call it - if(lua_pcall(L, 1, 0, 0)) - scriptError("error running function engine.button_handler: %s\n", - lua_tostring(L, -1)); + if(lua_pcall(L, 1, 0, errorhandler)) + scriptError(); + lua_pop(L, 1); // Pop error handler } diff --git a/src/script/cpp_api/s_node.cpp b/src/script/cpp_api/s_node.cpp index 92fd00a74..cd8451cf0 100644 --- a/src/script/cpp_api/s_node.cpp +++ b/src/script/cpp_api/s_node.cpp @@ -91,6 +91,9 @@ bool ScriptApiNode::node_on_punch(v3s16 p, MapNode node, { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + INodeDefManager *ndef = getServer()->ndef(); // Push callback function on stack @@ -101,8 +104,9 @@ bool ScriptApiNode::node_on_punch(v3s16 p, MapNode node, push_v3s16(L, p); pushnode(L, node, ndef); objectrefGetOrCreate(puncher); - if(lua_pcall(L, 3, 0, 0)) - scriptError("error: %s", lua_tostring(L, -1)); + if(lua_pcall(L, 3, 0, errorhandler)) + scriptError(); + lua_pop(L, 1); // Pop error handler return true; } @@ -111,6 +115,9 @@ bool ScriptApiNode::node_on_dig(v3s16 p, MapNode node, { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + INodeDefManager *ndef = getServer()->ndef(); // Push callback function on stack @@ -121,8 +128,9 @@ bool ScriptApiNode::node_on_dig(v3s16 p, MapNode node, push_v3s16(L, p); pushnode(L, node, ndef); objectrefGetOrCreate(digger); - if(lua_pcall(L, 3, 0, 0)) - scriptError("error: %s", lua_tostring(L, -1)); + if(lua_pcall(L, 3, 0, errorhandler)) + scriptError(); + lua_pop(L, 1); // Pop error handler return true; } @@ -130,6 +138,9 @@ void ScriptApiNode::node_on_construct(v3s16 p, MapNode node) { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + INodeDefManager *ndef = getServer()->ndef(); // Push callback function on stack @@ -138,14 +149,18 @@ void ScriptApiNode::node_on_construct(v3s16 p, MapNode node) // Call function push_v3s16(L, p); - if(lua_pcall(L, 1, 0, 0)) - scriptError("error: %s", lua_tostring(L, -1)); + if(lua_pcall(L, 1, 0, errorhandler)) + scriptError(); + lua_pop(L, 1); // Pop error handler } void ScriptApiNode::node_on_destruct(v3s16 p, MapNode node) { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + INodeDefManager *ndef = getServer()->ndef(); // Push callback function on stack @@ -154,14 +169,18 @@ void ScriptApiNode::node_on_destruct(v3s16 p, MapNode node) // Call function push_v3s16(L, p); - if(lua_pcall(L, 1, 0, 0)) - scriptError("error: %s", lua_tostring(L, -1)); + if(lua_pcall(L, 1, 0, errorhandler)) + scriptError(); + lua_pop(L, 1); // Pop error handler } void ScriptApiNode::node_after_destruct(v3s16 p, MapNode node) { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + INodeDefManager *ndef = getServer()->ndef(); // Push callback function on stack @@ -171,14 +190,18 @@ void ScriptApiNode::node_after_destruct(v3s16 p, MapNode node) // Call function push_v3s16(L, p); pushnode(L, node, ndef); - if(lua_pcall(L, 2, 0, 0)) - scriptError("error: %s", lua_tostring(L, -1)); + if(lua_pcall(L, 2, 0, errorhandler)) + scriptError(); + lua_pop(L, 1); // Pop error handler } bool ScriptApiNode::node_on_timer(v3s16 p, MapNode node, f32 dtime) { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + INodeDefManager *ndef = getServer()->ndef(); // Push callback function on stack @@ -188,12 +211,10 @@ bool ScriptApiNode::node_on_timer(v3s16 p, MapNode node, f32 dtime) // Call function push_v3s16(L, p); lua_pushnumber(L,dtime); - if(lua_pcall(L, 2, 1, 0)) - scriptError("error: %s", lua_tostring(L, -1)); - if((bool)lua_isboolean(L,-1) && (bool)lua_toboolean(L,-1) == true) - return true; - - return false; + if(lua_pcall(L, 2, 1, errorhandler)) + scriptError(); + lua_remove(L, errorhandler); // Remove error handler + return (bool) lua_isboolean(L, -1) && (bool) lua_toboolean(L, -1) == true; } void ScriptApiNode::node_on_receive_fields(v3s16 p, @@ -203,6 +224,9 @@ void ScriptApiNode::node_on_receive_fields(v3s16 p, { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + INodeDefManager *ndef = getServer()->ndef(); // If node doesn't exist, we don't know what callback to call @@ -215,12 +239,9 @@ void ScriptApiNode::node_on_receive_fields(v3s16 p, return; // Call function - // param 1 - push_v3s16(L, p); - // param 2 - lua_pushstring(L, formname.c_str()); - // param 3 - lua_newtable(L); + push_v3s16(L, p); // pos + lua_pushstring(L, formname.c_str()); // formname + lua_newtable(L); // fields for(std::map<std::string, std::string>::const_iterator i = fields.begin(); i != fields.end(); i++){ const std::string &name = i->first; @@ -229,26 +250,37 @@ void ScriptApiNode::node_on_receive_fields(v3s16 p, lua_pushlstring(L, value.c_str(), value.size()); lua_settable(L, -3); } - // param 4 - objectrefGetOrCreate(sender); - if(lua_pcall(L, 4, 0, 0)) - scriptError("error: %s", lua_tostring(L, -1)); + objectrefGetOrCreate(sender); // player + if(lua_pcall(L, 4, 0, errorhandler)) + scriptError(); + lua_pop(L, 1); // Pop error handler } void ScriptApiNode::node_falling_update(v3s16 p) { SCRIPTAPI_PRECHECKHEADER + + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + lua_getglobal(L, "nodeupdate"); push_v3s16(L, p); - if(lua_pcall(L, 1, 0, 0)) - scriptError("error: %s", lua_tostring(L, -1)); + if(lua_pcall(L, 1, 0, errorhandler)) + scriptError(); + lua_pop(L, 1); // Pop error handler } void ScriptApiNode::node_falling_update_single(v3s16 p) { SCRIPTAPI_PRECHECKHEADER + + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + lua_getglobal(L, "nodeupdate_single"); push_v3s16(L, p); - if(lua_pcall(L, 1, 0, 0)) - scriptError("error: %s", lua_tostring(L, -1)); + if(lua_pcall(L, 1, 0, errorhandler)) + scriptError(); + lua_pop(L, 1); // Pop error handler } + diff --git a/src/script/cpp_api/s_nodemeta.cpp b/src/script/cpp_api/s_nodemeta.cpp index e87464c61..1f04383f1 100644 --- a/src/script/cpp_api/s_nodemeta.cpp +++ b/src/script/cpp_api/s_nodemeta.cpp @@ -34,6 +34,9 @@ int ScriptApiNodemeta::nodemeta_inventory_AllowMove(v3s16 p, { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + INodeDefManager *ndef = getServer()->ndef(); // If node doesn't exist, we don't know what callback to call @@ -47,25 +50,21 @@ int ScriptApiNodemeta::nodemeta_inventory_AllowMove(v3s16 p, return count; // function(pos, from_list, from_index, to_list, to_index, count, player) - // pos - push_v3s16(L, p); - // from_list - lua_pushstring(L, from_list.c_str()); - // from_index - lua_pushinteger(L, from_index + 1); - // to_list - lua_pushstring(L, to_list.c_str()); - // to_index - lua_pushinteger(L, to_index + 1); - // count - lua_pushinteger(L, count); - // player - objectrefGetOrCreate(player); - if(lua_pcall(L, 7, 1, 0)) - scriptError("error: %s", lua_tostring(L, -1)); + push_v3s16(L, p); // pos + lua_pushstring(L, from_list.c_str()); // from_list + lua_pushinteger(L, from_index + 1); // from_index + lua_pushstring(L, to_list.c_str()); // to_list + lua_pushinteger(L, to_index + 1); // to_index + lua_pushinteger(L, count); // count + objectrefGetOrCreate(player); // player + if(lua_pcall(L, 7, 1, errorhandler)) + scriptError(); + lua_remove(L, errorhandler); // Remove error handler if(!lua_isnumber(L, -1)) throw LuaError(L, "allow_metadata_inventory_move should return a number"); - return luaL_checkinteger(L, -1); + int num = luaL_checkinteger(L, -1); + lua_pop(L, 1); // Pop integer + return num; } // Return number of accepted items to be put @@ -75,6 +74,9 @@ int ScriptApiNodemeta::nodemeta_inventory_AllowPut(v3s16 p, { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + INodeDefManager *ndef = getServer()->ndef(); // If node doesn't exist, we don't know what callback to call @@ -88,21 +90,19 @@ int ScriptApiNodemeta::nodemeta_inventory_AllowPut(v3s16 p, return stack.count; // Call function(pos, listname, index, stack, player) - // pos - push_v3s16(L, p); - // listname - lua_pushstring(L, listname.c_str()); - // index - lua_pushinteger(L, index + 1); - // stack - LuaItemStack::create(L, stack); - // player - objectrefGetOrCreate(player); - if(lua_pcall(L, 5, 1, 0)) - scriptError("error: %s", lua_tostring(L, -1)); + push_v3s16(L, p); // pos + lua_pushstring(L, listname.c_str()); // listname + lua_pushinteger(L, index + 1); // index + LuaItemStack::create(L, stack); // stack + objectrefGetOrCreate(player); // player + if(lua_pcall(L, 5, 1, errorhandler)) + scriptError(); + lua_remove(L, errorhandler); // Remove error handler if(!lua_isnumber(L, -1)) throw LuaError(L, "allow_metadata_inventory_put should return a number"); - return luaL_checkinteger(L, -1); + int num = luaL_checkinteger(L, -1); + lua_pop(L, 1); // Pop integer + return num; } // Return number of accepted items to be taken @@ -112,6 +112,9 @@ int ScriptApiNodemeta::nodemeta_inventory_AllowTake(v3s16 p, { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + INodeDefManager *ndef = getServer()->ndef(); // If node doesn't exist, we don't know what callback to call @@ -125,21 +128,19 @@ int ScriptApiNodemeta::nodemeta_inventory_AllowTake(v3s16 p, return stack.count; // Call function(pos, listname, index, count, player) - // pos - push_v3s16(L, p); - // listname - lua_pushstring(L, listname.c_str()); - // index - lua_pushinteger(L, index + 1); - // stack - LuaItemStack::create(L, stack); - // player - objectrefGetOrCreate(player); - if(lua_pcall(L, 5, 1, 0)) - scriptError("error: %s", lua_tostring(L, -1)); + push_v3s16(L, p); // pos + lua_pushstring(L, listname.c_str()); // listname + lua_pushinteger(L, index + 1); // index + LuaItemStack::create(L, stack); // stack + objectrefGetOrCreate(player); // player + if(lua_pcall(L, 5, 1, errorhandler)) + scriptError(); + lua_remove(L, errorhandler); // Remove error handler if(!lua_isnumber(L, -1)) throw LuaError(L, "allow_metadata_inventory_take should return a number"); - return luaL_checkinteger(L, -1); + int num = luaL_checkinteger(L, -1); + lua_pop(L, 1); // Pop integer + return num; } // Report moved items @@ -150,6 +151,9 @@ void ScriptApiNodemeta::nodemeta_inventory_OnMove(v3s16 p, { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + INodeDefManager *ndef = getServer()->ndef(); // If node doesn't exist, we don't know what callback to call @@ -163,22 +167,16 @@ void ScriptApiNodemeta::nodemeta_inventory_OnMove(v3s16 p, return; // function(pos, from_list, from_index, to_list, to_index, count, player) - // pos - push_v3s16(L, p); - // from_list - lua_pushstring(L, from_list.c_str()); - // from_index - lua_pushinteger(L, from_index + 1); - // to_list - lua_pushstring(L, to_list.c_str()); - // to_index - lua_pushinteger(L, to_index + 1); - // count - lua_pushinteger(L, count); - // player - objectrefGetOrCreate(player); - if(lua_pcall(L, 7, 0, 0)) - scriptError("error: %s", lua_tostring(L, -1)); + push_v3s16(L, p); // pos + lua_pushstring(L, from_list.c_str()); // from_list + lua_pushinteger(L, from_index + 1); // from_index + lua_pushstring(L, to_list.c_str()); // to_list + lua_pushinteger(L, to_index + 1); // to_index + lua_pushinteger(L, count); // count + objectrefGetOrCreate(player); // player + if(lua_pcall(L, 7, 0, errorhandler)) + scriptError(); + lua_pop(L, 1); // Pop error handler } // Report put items @@ -188,6 +186,9 @@ void ScriptApiNodemeta::nodemeta_inventory_OnPut(v3s16 p, { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + INodeDefManager *ndef = getServer()->ndef(); // If node doesn't exist, we don't know what callback to call @@ -201,18 +202,14 @@ void ScriptApiNodemeta::nodemeta_inventory_OnPut(v3s16 p, return; // Call function(pos, listname, index, stack, player) - // pos - push_v3s16(L, p); - // listname - lua_pushstring(L, listname.c_str()); - // index - lua_pushinteger(L, index + 1); - // stack - LuaItemStack::create(L, stack); - // player - objectrefGetOrCreate(player); - if(lua_pcall(L, 5, 0, 0)) - scriptError("error: %s", lua_tostring(L, -1)); + push_v3s16(L, p); // pos + lua_pushstring(L, listname.c_str()); // listname + lua_pushinteger(L, index + 1); // index + LuaItemStack::create(L, stack); // stack + objectrefGetOrCreate(player); // player + if(lua_pcall(L, 5, 0, errorhandler)) + scriptError(); + lua_pop(L, 1); // Pop error handler } // Report taken items @@ -222,6 +219,9 @@ void ScriptApiNodemeta::nodemeta_inventory_OnTake(v3s16 p, { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + INodeDefManager *ndef = getServer()->ndef(); // If node doesn't exist, we don't know what callback to call @@ -235,18 +235,14 @@ void ScriptApiNodemeta::nodemeta_inventory_OnTake(v3s16 p, return; // Call function(pos, listname, index, stack, player) - // pos - push_v3s16(L, p); - // listname - lua_pushstring(L, listname.c_str()); - // index - lua_pushinteger(L, index + 1); - // stack - LuaItemStack::create(L, stack); - // player - objectrefGetOrCreate(player); - if(lua_pcall(L, 5, 0, 0)) - scriptError("error: %s", lua_tostring(L, -1)); + push_v3s16(L, p); // pos + lua_pushstring(L, listname.c_str()); // listname + lua_pushinteger(L, index + 1); // index + LuaItemStack::create(L, stack); // stack + objectrefGetOrCreate(player); // player + if(lua_pcall(L, 5, 0, errorhandler)) + scriptError(); + lua_pop(L, 1); // Pop error handler } ScriptApiNodemeta::ScriptApiNodemeta() { diff --git a/src/script/cpp_api/s_server.cpp b/src/script/cpp_api/s_server.cpp index d41805b7b..4baf90636 100644 --- a/src/script/cpp_api/s_server.cpp +++ b/src/script/cpp_api/s_server.cpp @@ -27,13 +27,18 @@ bool ScriptApiServer::getAuth(const std::string &playername, { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + 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)); + if(lua_pcall(L, 1, 1, errorhandler)) + scriptError(); + lua_remove(L, -2); // Remove auth handler + lua_remove(L, errorhandler); // Remove error handler // nil = login not allowed if(lua_isnil(L, -1)) @@ -49,8 +54,7 @@ bool ScriptApiServer::getAuth(const std::string &playername, lua_getfield(L, -1, "privileges"); if(!lua_istable(L, -1)) - throw LuaError(L, - "Authentication handler didn't return privilege table"); + throw LuaError(L, "Authentication handler didn't return privilege table"); if(dst_privs) readPrivileges(-1, *dst_privs); lua_pop(L, 1); @@ -68,6 +72,7 @@ void ScriptApiServer::getAuthHandler() lua_pop(L, 1); lua_getfield(L, -1, "builtin_auth_handler"); } + lua_remove(L, -2); // Remove minetest if(lua_type(L, -1) != LUA_TTABLE) throw LuaError(L, "Authentication handler table not valid"); } @@ -96,14 +101,19 @@ void ScriptApiServer::createAuth(const std::string &playername, { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + getAuthHandler(); lua_getfield(L, -1, "create_auth"); + lua_remove(L, -2); // Remove auth handler 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)); + if(lua_pcall(L, 2, 0, errorhandler)) + scriptError(); + lua_pop(L, 1); // Pop error handler } bool ScriptApiServer::setPassword(const std::string &playername, @@ -111,14 +121,19 @@ bool ScriptApiServer::setPassword(const std::string &playername, { SCRIPTAPI_PRECHECKHEADER + lua_pushcfunction(L, script_error_handler); + int errorhandler = lua_gettop(L); + getAuthHandler(); lua_getfield(L, -1, "set_password"); + lua_remove(L, -2); // Remove auth handler 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)); + if(lua_pcall(L, 2, 1, errorhandler)) + scriptError(); + lua_remove(L, -2); // Remove error handler return lua_toboolean(L, -1); } |