Only push the Lua error handler once

master
ShadowNinja 2014-04-15 13:30:46 -04:00
parent 1838a3fd69
commit db4ea4658c
9 changed files with 154 additions and 279 deletions

View File

@ -72,6 +72,10 @@ ScriptApiBase::ScriptApiBase()
m_luastack = luaL_newstate(); m_luastack = luaL_newstate();
assert(m_luastack); assert(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 // Make the ScriptApiBase* accessible to ModApiBase
lua_pushlightuserdata(m_luastack, this); lua_pushlightuserdata(m_luastack, this);
lua_setfield(m_luastack, LUA_REGISTRYINDEX, "scriptapi"); lua_setfield(m_luastack, LUA_REGISTRYINDEX, "scriptapi");
@ -125,23 +129,18 @@ bool ScriptApiBase::loadScript(const std::string &scriptpath)
lua_State *L = getStack(); lua_State *L = getStack();
lua_pushcfunction(L, script_error_handler); int ret = luaL_loadfile(L, scriptpath.c_str()) || lua_pcall(L, 0, 0, m_errorhandler);
int errorhandler = lua_gettop(L); if (ret) {
errorstream << "========== ERROR FROM LUA ===========" << std::endl;
int ret = luaL_loadfile(L, scriptpath.c_str()) || lua_pcall(L, 0, 0, errorhandler); errorstream << "Failed to load and run script from " << std::endl;
if(ret){ errorstream << scriptpath << ":" << std::endl;
errorstream<<"========== ERROR FROM LUA ==========="<<std::endl; errorstream << std::endl;
errorstream<<"Failed to load and run script from "<<std::endl; errorstream << lua_tostring(L, -1) << std::endl;
errorstream<<scriptpath<<":"<<std::endl; errorstream << std::endl;
errorstream<<std::endl; errorstream << "======= END OF ERROR FROM LUA ========" << std::endl;
errorstream<<lua_tostring(L, -1)<<std::endl;
errorstream<<std::endl;
errorstream<<"======= END OF ERROR FROM LUA ========"<<std::endl;
lua_pop(L, 1); // Pop error message from stack lua_pop(L, 1); // Pop error message from stack
lua_pop(L, 1); // Pop the error handler from stack
return false; return false;
} }
lua_pop(L, 1); // Pop the error handler from stack
return true; return true;
} }

View File

@ -82,9 +82,12 @@ protected:
void objectrefGet(u16 id); void objectrefGet(u16 id);
JMutex m_luastackmutex; JMutex m_luastackmutex;
// Stack index of Lua error handler
int m_errorhandler;
#ifdef SCRIPTAPI_LOCK_DEBUG #ifdef SCRIPTAPI_LOCK_DEBUG
bool m_locked; bool m_locked;
#endif #endif
private: private:
lua_State* m_luastack; lua_State* m_luastack;

View File

@ -39,7 +39,7 @@ bool ScriptApiEntity::luaentity_Add(u16 id, const char *name)
lua_gettable(L, -2); lua_gettable(L, -2);
// Should be a table, which we will use as a prototype // Should be a table, which we will use as a prototype
//luaL_checktype(L, -1, LUA_TTABLE); //luaL_checktype(L, -1, LUA_TTABLE);
if(lua_type(L, -1) != LUA_TTABLE){ if (lua_type(L, -1) != LUA_TTABLE){
errorstream<<"LuaEntity name \""<<name<<"\" not defined"<<std::endl; errorstream<<"LuaEntity name \""<<name<<"\" not defined"<<std::endl;
return false; return false;
} }
@ -58,7 +58,7 @@ bool ScriptApiEntity::luaentity_Add(u16 id, const char *name)
// This should be userdata with metatable ObjectRef // This should be userdata with metatable ObjectRef
objectrefGet(id); objectrefGet(id);
luaL_checktype(L, -1, LUA_TUSERDATA); luaL_checktype(L, -1, LUA_TUSERDATA);
if(!luaL_checkudata(L, -1, "ObjectRef")) if (!luaL_checkudata(L, -1, "ObjectRef"))
luaL_typerror(L, -1, "ObjectRef"); luaL_typerror(L, -1, "ObjectRef");
lua_setfield(L, -2, "object"); lua_setfield(L, -2, "object");
@ -78,10 +78,7 @@ void ScriptApiEntity::luaentity_Activate(u16 id,
{ {
SCRIPTAPI_PRECHECKHEADER SCRIPTAPI_PRECHECKHEADER
lua_pushcfunction(L, script_error_handler); verbosestream << "scriptapi_luaentity_activate: id=" << id << std::endl;
int errorhandler = lua_gettop(L);
verbosestream<<"scriptapi_luaentity_activate: id="<<id<<std::endl;
// Get minetest.luaentities[id] // Get minetest.luaentities[id]
luaentity_get(L, id); luaentity_get(L, id);
@ -89,25 +86,25 @@ void ScriptApiEntity::luaentity_Activate(u16 id,
// Get on_activate function // Get on_activate function
lua_getfield(L, -1, "on_activate"); lua_getfield(L, -1, "on_activate");
if(!lua_isnil(L, -1)) { if (!lua_isnil(L, -1)) {
luaL_checktype(L, -1, LUA_TFUNCTION); luaL_checktype(L, -1, LUA_TFUNCTION);
lua_pushvalue(L, object); // self lua_pushvalue(L, object); // self
lua_pushlstring(L, staticdata.c_str(), staticdata.size()); lua_pushlstring(L, staticdata.c_str(), staticdata.size());
lua_pushinteger(L, dtime_s); lua_pushinteger(L, dtime_s);
// Call with 3 arguments, 0 results // Call with 3 arguments, 0 results
if(lua_pcall(L, 3, 0, errorhandler)) if (lua_pcall(L, 3, 0, m_errorhandler))
scriptError(); scriptError();
} else { } else {
lua_pop(L, 1); lua_pop(L, 1);
} }
lua_pop(L, 2); // Pop object and error handler lua_pop(L, 1); // Pop object
} }
void ScriptApiEntity::luaentity_Remove(u16 id) void ScriptApiEntity::luaentity_Remove(u16 id)
{ {
SCRIPTAPI_PRECHECKHEADER SCRIPTAPI_PRECHECKHEADER
verbosestream<<"scriptapi_luaentity_rm: id="<<id<<std::endl; verbosestream << "scriptapi_luaentity_rm: id=" << id << std::endl;
// Get minetest.luaentities table // Get minetest.luaentities table
lua_getglobal(L, "minetest"); lua_getglobal(L, "minetest");
@ -127,9 +124,6 @@ std::string ScriptApiEntity::luaentity_GetStaticdata(u16 id)
{ {
SCRIPTAPI_PRECHECKHEADER SCRIPTAPI_PRECHECKHEADER
lua_pushcfunction(L, script_error_handler);
int errorhandler = lua_gettop(L);
//infostream<<"scriptapi_luaentity_get_staticdata: id="<<id<<std::endl; //infostream<<"scriptapi_luaentity_get_staticdata: id="<<id<<std::endl;
// Get minetest.luaentities[id] // Get minetest.luaentities[id]
@ -138,19 +132,21 @@ std::string ScriptApiEntity::luaentity_GetStaticdata(u16 id)
// Get get_staticdata function // Get get_staticdata function
lua_getfield(L, -1, "get_staticdata"); lua_getfield(L, -1, "get_staticdata");
if(lua_isnil(L, -1)) if (lua_isnil(L, -1)) {
lua_pop(L, 2); // Pop entity and get_staticdata
return ""; return "";
}
luaL_checktype(L, -1, LUA_TFUNCTION); luaL_checktype(L, -1, LUA_TFUNCTION);
lua_pushvalue(L, object); // self lua_pushvalue(L, object); // self
// Call with 1 arguments, 1 results // Call with 1 arguments, 1 results
if(lua_pcall(L, 1, 1, errorhandler)) if (lua_pcall(L, 1, 1, m_errorhandler))
scriptError(); scriptError();
lua_remove(L, object); // Remove object 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); const char *s = lua_tolstring(L, -1, &len);
lua_pop(L, 1); // Pop static data
return std::string(s, len); return std::string(s, len);
} }
@ -162,8 +158,7 @@ void ScriptApiEntity::luaentity_GetProperties(u16 id,
//infostream<<"scriptapi_luaentity_get_properties: id="<<id<<std::endl; //infostream<<"scriptapi_luaentity_get_properties: id="<<id<<std::endl;
// Get minetest.luaentities[id] // Get minetest.luaentities[id]
luaentity_get(L,id); luaentity_get(L, id);
//int object = lua_gettop(L);
// Set default values that differ from ObjectProperties defaults // Set default values that differ from ObjectProperties defaults
prop->hp_max = 10; prop->hp_max = 10;
@ -178,7 +173,7 @@ void ScriptApiEntity::luaentity_GetProperties(u16 id,
getfloatfield(L, -1, "weight", prop->weight); getfloatfield(L, -1, "weight", prop->weight);
lua_getfield(L, -1, "collisionbox"); lua_getfield(L, -1, "collisionbox");
if(lua_istable(L, -1)) if (lua_istable(L, -1))
prop->collisionbox = read_aabb3f(L, -1, 1.0); prop->collisionbox = read_aabb3f(L, -1, 1.0);
lua_pop(L, 1); lua_pop(L, 1);
@ -199,9 +194,6 @@ void ScriptApiEntity::luaentity_Step(u16 id, float dtime)
{ {
SCRIPTAPI_PRECHECKHEADER SCRIPTAPI_PRECHECKHEADER
lua_pushcfunction(L, script_error_handler);
int errorhandler = lua_gettop(L);
//infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl; //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
// Get minetest.luaentities[id] // Get minetest.luaentities[id]
@ -210,16 +202,17 @@ void ScriptApiEntity::luaentity_Step(u16 id, float dtime)
// State: object is at top of stack // State: object is at top of stack
// Get step function // Get step function
lua_getfield(L, -1, "on_step"); lua_getfield(L, -1, "on_step");
if(lua_isnil(L, -1)) if (lua_isnil(L, -1)) {
lua_pop(L, 2); // Pop on_step and entity
return; return;
}
luaL_checktype(L, -1, LUA_TFUNCTION); luaL_checktype(L, -1, LUA_TFUNCTION);
lua_pushvalue(L, object); // self lua_pushvalue(L, object); // self
lua_pushnumber(L, dtime); // dtime lua_pushnumber(L, dtime); // dtime
// Call with 2 arguments, 0 results // Call with 2 arguments, 0 results
if(lua_pcall(L, 2, 0, errorhandler)) if (lua_pcall(L, 2, 0, m_errorhandler))
scriptError(); scriptError();
lua_remove(L, object); // Remove object lua_pop(L, 1); // Pop object
lua_remove(L, errorhandler); // Remove error handler
} }
// Calls entity:on_punch(ObjectRef puncher, time_from_last_punch, // Calls entity:on_punch(ObjectRef puncher, time_from_last_punch,
@ -230,9 +223,6 @@ void ScriptApiEntity::luaentity_Punch(u16 id,
{ {
SCRIPTAPI_PRECHECKHEADER SCRIPTAPI_PRECHECKHEADER
lua_pushcfunction(L, script_error_handler);
int errorhandler = lua_gettop(L);
//infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl; //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
// Get minetest.luaentities[id] // Get minetest.luaentities[id]
@ -241,19 +231,20 @@ void ScriptApiEntity::luaentity_Punch(u16 id,
// State: object is at top of stack // State: object is at top of stack
// Get function // Get function
lua_getfield(L, -1, "on_punch"); lua_getfield(L, -1, "on_punch");
if(lua_isnil(L, -1)) if (lua_isnil(L, -1)) {
lua_pop(L, 2); // Pop on_punch and entitu
return; return;
}
luaL_checktype(L, -1, LUA_TFUNCTION); luaL_checktype(L, -1, LUA_TFUNCTION);
lua_pushvalue(L, object); // self lua_pushvalue(L, object); // self
objectrefGetOrCreate(puncher); // Clicker reference objectrefGetOrCreate(puncher); // Clicker reference
lua_pushnumber(L, time_from_last_punch); lua_pushnumber(L, time_from_last_punch);
push_tool_capabilities(L, *toolcap); push_tool_capabilities(L, *toolcap);
push_v3f(L, dir); push_v3f(L, dir);
// Call with 5 arguments, 0 results // Call with 5 arguments, 0 results
if(lua_pcall(L, 5, 0, errorhandler)) if (lua_pcall(L, 5, 0, m_errorhandler))
scriptError(); scriptError();
lua_remove(L, object); // Remove object lua_pop(L, 1); // Pop object
lua_remove(L, errorhandler); // Remove error handler
} }
// Calls entity:on_rightclick(ObjectRef clicker) // Calls entity:on_rightclick(ObjectRef clicker)
@ -262,26 +253,24 @@ void ScriptApiEntity::luaentity_Rightclick(u16 id,
{ {
SCRIPTAPI_PRECHECKHEADER SCRIPTAPI_PRECHECKHEADER
lua_pushcfunction(L, script_error_handler);
int errorhandler = lua_gettop(L);
//infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl; //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
// Get minetest.luaentities[id] // Get minetest.luaentities[id]
luaentity_get(L,id); luaentity_get(L, id);
int object = lua_gettop(L); int object = lua_gettop(L);
// State: object is at top of stack // State: object is at top of stack
// Get function // Get function
lua_getfield(L, -1, "on_rightclick"); lua_getfield(L, -1, "on_rightclick");
if(lua_isnil(L, -1)) if (lua_isnil(L, -1)) {
lua_pop(L, 2); // Pop on_rightclick and entity
return; return;
}
luaL_checktype(L, -1, LUA_TFUNCTION); luaL_checktype(L, -1, LUA_TFUNCTION);
lua_pushvalue(L, object); // self lua_pushvalue(L, object); // self
objectrefGetOrCreate(clicker); // Clicker reference objectrefGetOrCreate(clicker); // Clicker reference
// Call with 2 arguments, 0 results // Call with 2 arguments, 0 results
if(lua_pcall(L, 2, 0, errorhandler)) if (lua_pcall(L, 2, 0, m_errorhandler))
scriptError(); scriptError();
lua_remove(L, object); // Remove object lua_pop(L, 1); // Pop object
lua_remove(L, errorhandler); // Remove error handler
} }

View File

@ -33,11 +33,8 @@ int ScriptApiDetached::detached_inventory_AllowMove(
{ {
SCRIPTAPI_PRECHECKHEADER SCRIPTAPI_PRECHECKHEADER
lua_pushcfunction(L, script_error_handler);
int errorhandler = lua_gettop(L);
// Push callback function on stack // Push callback function on stack
if(!getDetachedInventoryCallback(name, "allow_move")) if (!getDetachedInventoryCallback(name, "allow_move"))
return count; return count;
// function(inv, from_list, from_index, to_list, to_index, count, player) // function(inv, from_list, from_index, to_list, to_index, count, player)
@ -51,12 +48,12 @@ int ScriptApiDetached::detached_inventory_AllowMove(
lua_pushinteger(L, to_index + 1); // to_index lua_pushinteger(L, to_index + 1); // to_index
lua_pushinteger(L, count); // count lua_pushinteger(L, count); // count
objectrefGetOrCreate(player); // player objectrefGetOrCreate(player); // player
if(lua_pcall(L, 7, 1, errorhandler)) if (lua_pcall(L, 7, 1, m_errorhandler))
scriptError(); scriptError();
if(!lua_isnumber(L, -1)) if(!lua_isnumber(L, -1))
throw LuaError("allow_move should return a number. name=" + name); throw LuaError("allow_move should return a number. name=" + name);
int ret = luaL_checkinteger(L, -1); int ret = luaL_checkinteger(L, -1);
lua_pop(L, 2); // Pop integer and error handler lua_pop(L, 1); // Pop integer
return ret; return ret;
} }
@ -68,11 +65,8 @@ int ScriptApiDetached::detached_inventory_AllowPut(
{ {
SCRIPTAPI_PRECHECKHEADER SCRIPTAPI_PRECHECKHEADER
lua_pushcfunction(L, script_error_handler);
int errorhandler = lua_gettop(L);
// Push callback function on stack // Push callback function on stack
if(!getDetachedInventoryCallback(name, "allow_put")) if (!getDetachedInventoryCallback(name, "allow_put"))
return stack.count; // All will be accepted return stack.count; // All will be accepted
// Call function(inv, listname, index, stack, player) // Call function(inv, listname, index, stack, player)
@ -83,12 +77,12 @@ int ScriptApiDetached::detached_inventory_AllowPut(
lua_pushinteger(L, index + 1); // index lua_pushinteger(L, index + 1); // index
LuaItemStack::create(L, stack); // stack LuaItemStack::create(L, stack); // stack
objectrefGetOrCreate(player); // player objectrefGetOrCreate(player); // player
if(lua_pcall(L, 5, 1, errorhandler)) if (lua_pcall(L, 5, 1, m_errorhandler))
scriptError(); scriptError();
if(!lua_isnumber(L, -1)) if (!lua_isnumber(L, -1))
throw LuaError("allow_put should return a number. name=" + name); throw LuaError("allow_put should return a number. name=" + name);
int ret = luaL_checkinteger(L, -1); int ret = luaL_checkinteger(L, -1);
lua_pop(L, 2); // Pop integer and error handler lua_pop(L, 1); // Pop integer
return ret; return ret;
} }
@ -100,11 +94,8 @@ int ScriptApiDetached::detached_inventory_AllowTake(
{ {
SCRIPTAPI_PRECHECKHEADER SCRIPTAPI_PRECHECKHEADER
lua_pushcfunction(L, script_error_handler);
int errorhandler = lua_gettop(L);
// Push callback function on stack // Push callback function on stack
if(!getDetachedInventoryCallback(name, "allow_take")) if (!getDetachedInventoryCallback(name, "allow_take"))
return stack.count; // All will be accepted return stack.count; // All will be accepted
// Call function(inv, listname, index, stack, player) // Call function(inv, listname, index, stack, player)
@ -115,12 +106,12 @@ int ScriptApiDetached::detached_inventory_AllowTake(
lua_pushinteger(L, index + 1); // index lua_pushinteger(L, index + 1); // index
LuaItemStack::create(L, stack); // stack LuaItemStack::create(L, stack); // stack
objectrefGetOrCreate(player); // player objectrefGetOrCreate(player); // player
if(lua_pcall(L, 5, 1, errorhandler)) if (lua_pcall(L, 5, 1, m_errorhandler))
scriptError(); scriptError();
if(!lua_isnumber(L, -1)) if (!lua_isnumber(L, -1))
throw LuaError("allow_take should return a number. name=" + name); throw LuaError("allow_take should return a number. name=" + name);
int ret = luaL_checkinteger(L, -1); int ret = luaL_checkinteger(L, -1);
lua_pop(L, 2); // Pop integer and error handler lua_pop(L, 1); // Pop integer
return ret; return ret;
} }
@ -133,11 +124,8 @@ void ScriptApiDetached::detached_inventory_OnMove(
{ {
SCRIPTAPI_PRECHECKHEADER SCRIPTAPI_PRECHECKHEADER
lua_pushcfunction(L, script_error_handler);
int errorhandler = lua_gettop(L);
// Push callback function on stack // Push callback function on stack
if(!getDetachedInventoryCallback(name, "on_move")) if (!getDetachedInventoryCallback(name, "on_move"))
return; return;
// function(inv, from_list, from_index, to_list, to_index, count, player) // function(inv, from_list, from_index, to_list, to_index, count, player)
@ -151,9 +139,8 @@ void ScriptApiDetached::detached_inventory_OnMove(
lua_pushinteger(L, to_index + 1); // to_index lua_pushinteger(L, to_index + 1); // to_index
lua_pushinteger(L, count); // count lua_pushinteger(L, count); // count
objectrefGetOrCreate(player); // player objectrefGetOrCreate(player); // player
if(lua_pcall(L, 7, 0, errorhandler)) if (lua_pcall(L, 7, 0, m_errorhandler))
scriptError(); scriptError();
lua_pop(L, 1); // Pop error handler
} }
// Report put items // Report put items
@ -164,11 +151,8 @@ void ScriptApiDetached::detached_inventory_OnPut(
{ {
SCRIPTAPI_PRECHECKHEADER SCRIPTAPI_PRECHECKHEADER
lua_pushcfunction(L, script_error_handler);
int errorhandler = lua_gettop(L);
// Push callback function on stack // Push callback function on stack
if(!getDetachedInventoryCallback(name, "on_put")) if (!getDetachedInventoryCallback(name, "on_put"))
return; return;
// Call function(inv, listname, index, stack, player) // Call function(inv, listname, index, stack, player)
@ -180,9 +164,8 @@ void ScriptApiDetached::detached_inventory_OnPut(
lua_pushinteger(L, index + 1); // index lua_pushinteger(L, index + 1); // index
LuaItemStack::create(L, stack); // stack LuaItemStack::create(L, stack); // stack
objectrefGetOrCreate(player); // player objectrefGetOrCreate(player); // player
if(lua_pcall(L, 5, 0, errorhandler)) if (lua_pcall(L, 5, 0, m_errorhandler))
scriptError(); scriptError();
lua_pop(L, 1); // Pop error handler
} }
// Report taken items // Report taken items
@ -193,11 +176,8 @@ void ScriptApiDetached::detached_inventory_OnTake(
{ {
SCRIPTAPI_PRECHECKHEADER SCRIPTAPI_PRECHECKHEADER
lua_pushcfunction(L, script_error_handler);
int errorhandler = lua_gettop(L);
// Push callback function on stack // Push callback function on stack
if(!getDetachedInventoryCallback(name, "on_take")) if (!getDetachedInventoryCallback(name, "on_take"))
return; return;
// Call function(inv, listname, index, stack, player) // Call function(inv, listname, index, stack, player)
@ -209,9 +189,8 @@ void ScriptApiDetached::detached_inventory_OnTake(
lua_pushinteger(L, index + 1); // index lua_pushinteger(L, index + 1); // index
LuaItemStack::create(L, stack); // stack LuaItemStack::create(L, stack); // stack
objectrefGetOrCreate(player); // player objectrefGetOrCreate(player); // player
if(lua_pcall(L, 5, 0, errorhandler)) if (lua_pcall(L, 5, 0, m_errorhandler))
scriptError(); scriptError();
lua_pop(L, 1); // Pop error handler
} }
// Retrieves minetest.detached_inventories[name][callbackname] // Retrieves minetest.detached_inventories[name][callbackname]

View File

@ -34,27 +34,24 @@ bool ScriptApiItem::item_OnDrop(ItemStack &item,
{ {
SCRIPTAPI_PRECHECKHEADER SCRIPTAPI_PRECHECKHEADER
lua_pushcfunction(L, script_error_handler);
int errorhandler = lua_gettop(L);
// Push callback function on stack // Push callback function on stack
if(!getItemCallback(item.name.c_str(), "on_drop")) if (!getItemCallback(item.name.c_str(), "on_drop"))
return false; return false;
// Call function // Call function
LuaItemStack::create(L, item); LuaItemStack::create(L, item);
objectrefGetOrCreate(dropper); objectrefGetOrCreate(dropper);
pushFloatPos(L, pos); pushFloatPos(L, pos);
if(lua_pcall(L, 3, 1, errorhandler)) if (lua_pcall(L, 3, 1, m_errorhandler))
scriptError(); scriptError();
if(!lua_isnil(L, -1)) { if (!lua_isnil(L, -1)) {
try { try {
item = read_item(L,-1, getServer()); item = read_item(L,-1, getServer());
} catch (LuaError &e) { } catch (LuaError &e) {
throw LuaError(std::string(e.what()) + ". item=" + item.name); throw LuaError(std::string(e.what()) + ". item=" + item.name);
} }
} }
lua_pop(L, 2); // Pop item and error handler lua_pop(L, 1); // Pop item
return true; return true;
} }
@ -63,27 +60,24 @@ bool ScriptApiItem::item_OnPlace(ItemStack &item,
{ {
SCRIPTAPI_PRECHECKHEADER SCRIPTAPI_PRECHECKHEADER
lua_pushcfunction(L, script_error_handler);
int errorhandler = lua_gettop(L);
// Push callback function on stack // Push callback function on stack
if(!getItemCallback(item.name.c_str(), "on_place")) if (!getItemCallback(item.name.c_str(), "on_place"))
return false; return false;
// Call function // Call function
LuaItemStack::create(L, item); LuaItemStack::create(L, item);
objectrefGetOrCreate(placer); objectrefGetOrCreate(placer);
pushPointedThing(pointed); pushPointedThing(pointed);
if(lua_pcall(L, 3, 1, errorhandler)) if (lua_pcall(L, 3, 1, m_errorhandler))
scriptError(); scriptError();
if(!lua_isnil(L, -1)) { if (!lua_isnil(L, -1)) {
try { try {
item = read_item(L,-1, getServer()); item = read_item(L,-1, getServer());
} catch (LuaError &e) { } catch (LuaError &e) {
throw LuaError(std::string(e.what()) + ". item=" + item.name); throw LuaError(std::string(e.what()) + ". item=" + item.name);
} }
} }
lua_pop(L, 2); // Pop item and error handler lua_pop(L, 1); // Pop item
return true; return true;
} }
@ -92,18 +86,15 @@ bool ScriptApiItem::item_OnUse(ItemStack &item,
{ {
SCRIPTAPI_PRECHECKHEADER SCRIPTAPI_PRECHECKHEADER
lua_pushcfunction(L, script_error_handler);
int errorhandler = lua_gettop(L);
// Push callback function on stack // Push callback function on stack
if(!getItemCallback(item.name.c_str(), "on_use")) if (!getItemCallback(item.name.c_str(), "on_use"))
return false; return false;
// Call function // Call function
LuaItemStack::create(L, item); LuaItemStack::create(L, item);
objectrefGetOrCreate(user); objectrefGetOrCreate(user);
pushPointedThing(pointed); pushPointedThing(pointed);
if(lua_pcall(L, 3, 1, errorhandler)) if (lua_pcall(L, 3, 1, m_errorhandler))
scriptError(); scriptError();
if(!lua_isnil(L, -1)) { if(!lua_isnil(L, -1)) {
try { try {
@ -112,7 +103,7 @@ bool ScriptApiItem::item_OnUse(ItemStack &item,
throw LuaError(std::string(e.what()) + ". item=" + item.name); throw LuaError(std::string(e.what()) + ". item=" + item.name);
} }
} }
lua_pop(L, 2); // Pop item and error handler lua_pop(L, 1); // Pop item
return true; return true;
} }
@ -121,31 +112,29 @@ bool ScriptApiItem::item_OnCraft(ItemStack &item, ServerActiveObject *user,
{ {
SCRIPTAPI_PRECHECKHEADER SCRIPTAPI_PRECHECKHEADER
lua_pushcfunction(L, script_error_handler);
int errorhandler = lua_gettop(L);
lua_getglobal(L, "minetest"); lua_getglobal(L, "minetest");
lua_getfield(L, -1, "on_craft"); lua_getfield(L, -1, "on_craft");
LuaItemStack::create(L, item); LuaItemStack::create(L, item);
objectrefGetOrCreate(user); objectrefGetOrCreate(user);
//Push inventory list // Push inventory list
std::vector<ItemStack> items; std::vector<ItemStack> items;
for(u32 i=0; i<old_craft_grid->getSize(); i++) for (u32 i = 0; i < old_craft_grid->getSize(); i++) {
items.push_back(old_craft_grid->getItem(i)); items.push_back(old_craft_grid->getItem(i));
}
push_items(L, items); push_items(L, items);
InvRef::create(L, craft_inv); InvRef::create(L, craft_inv);
if(lua_pcall(L, 4, 1, errorhandler)) if (lua_pcall(L, 4, 1, m_errorhandler))
scriptError(); scriptError();
if(!lua_isnil(L, -1)) { if (!lua_isnil(L, -1)) {
try { try {
item = read_item(L,-1, getServer()); item = read_item(L,-1, getServer());
} catch (LuaError &e) { } catch (LuaError &e) {
throw LuaError(std::string(e.what()) + ". item=" + item.name); throw LuaError(std::string(e.what()) + ". item=" + item.name);
} }
} }
lua_pop(L, 2); // Pop item and error handler lua_pop(L, 1); // Pop item
return true; return true;
} }
@ -154,9 +143,6 @@ bool ScriptApiItem::item_CraftPredict(ItemStack &item, ServerActiveObject *user,
{ {
SCRIPTAPI_PRECHECKHEADER SCRIPTAPI_PRECHECKHEADER
lua_pushcfunction(L, script_error_handler);
int errorhandler = lua_gettop(L);
lua_getglobal(L, "minetest"); lua_getglobal(L, "minetest");
lua_getfield(L, -1, "craft_predict"); lua_getfield(L, -1, "craft_predict");
LuaItemStack::create(L, item); LuaItemStack::create(L, item);
@ -164,21 +150,22 @@ bool ScriptApiItem::item_CraftPredict(ItemStack &item, ServerActiveObject *user,
//Push inventory list //Push inventory list
std::vector<ItemStack> items; std::vector<ItemStack> items;
for(u32 i=0; i<old_craft_grid->getSize(); i++) for (u32 i = 0; i < old_craft_grid->getSize(); i++) {
items.push_back(old_craft_grid->getItem(i)); items.push_back(old_craft_grid->getItem(i));
}
push_items(L, items); push_items(L, items);
InvRef::create(L, craft_inv); InvRef::create(L, craft_inv);
if(lua_pcall(L, 4, 1, errorhandler)) if (lua_pcall(L, 4, 1, m_errorhandler))
scriptError(); scriptError();
if(!lua_isnil(L, -1)) { if (!lua_isnil(L, -1)) {
try { try {
item = read_item(L,-1, getServer()); item = read_item(L,-1, getServer());
} catch (LuaError &e) { } catch (LuaError &e) {
throw LuaError(std::string(e.what()) + ". item=" + item.name); throw LuaError(std::string(e.what()) + ". item=" + item.name);
} }
} }
lua_pop(L, 2); // Pop item and error handler lua_pop(L, 1); // Pop item
return true; return true;
} }
@ -252,4 +239,3 @@ void ScriptApiItem::pushPointedThing(const PointedThing& pointed)
} }
} }

View File

@ -37,14 +37,11 @@ void ScriptApiMainMenu::handleMainMenuEvent(std::string text)
{ {
SCRIPTAPI_PRECHECKHEADER SCRIPTAPI_PRECHECKHEADER
lua_pushcfunction(L, script_error_handler);
int errorhandler = lua_gettop(L);
// Get handler function // Get handler function
lua_getglobal(L, "engine"); lua_getglobal(L, "engine");
lua_getfield(L, -1, "event_handler"); lua_getfield(L, -1, "event_handler");
lua_remove(L, -2); // Remove engine lua_remove(L, -2); // Remove engine
if(lua_isnil(L, -1)) { if (lua_isnil(L, -1)) {
lua_pop(L, 1); // Pop event_handler lua_pop(L, 1); // Pop event_handler
return; return;
} }
@ -52,41 +49,37 @@ void ScriptApiMainMenu::handleMainMenuEvent(std::string text)
// Call it // Call it
lua_pushstring(L, text.c_str()); lua_pushstring(L, text.c_str());
if(lua_pcall(L, 1, 0, errorhandler)) if (lua_pcall(L, 1, 0, m_errorhandler))
scriptError(); scriptError();
lua_pop(L, 1); // Pop error handler
} }
void ScriptApiMainMenu::handleMainMenuButtons(std::map<std::string, std::string> fields) void ScriptApiMainMenu::handleMainMenuButtons(std::map<std::string, std::string> fields)
{ {
SCRIPTAPI_PRECHECKHEADER SCRIPTAPI_PRECHECKHEADER
lua_pushcfunction(L, script_error_handler);
int errorhandler = lua_gettop(L);
// Get handler function // Get handler function
lua_getglobal(L, "engine"); lua_getglobal(L, "engine");
lua_getfield(L, -1, "button_handler"); lua_getfield(L, -1, "button_handler");
lua_remove(L, -2); // Remove engine lua_remove(L, -2); // Remove engine
if(lua_isnil(L, -1)) { if (lua_isnil(L, -1)) {
lua_pop(L, 1); // Pop button handler lua_pop(L, 1); // Pop button handler
return; return;
} }
luaL_checktype(L, -1, LUA_TFUNCTION); luaL_checktype(L, -1, LUA_TFUNCTION);
// Convert fields to lua table // Convert fields to a Lua table
lua_newtable(L); lua_newtable(L);
for(std::map<std::string, std::string>::const_iterator std::map<std::string, std::string>::const_iterator it;
i = fields.begin(); i != fields.end(); i++){ for (it = fields.begin(); it != fields.end(); it++){
const std::string &name = i->first; const std::string &name = it->first;
const std::string &value = i->second; const std::string &value = it->second;
lua_pushstring(L, name.c_str()); lua_pushstring(L, name.c_str());
lua_pushlstring(L, value.c_str(), value.size()); lua_pushlstring(L, value.c_str(), value.size());
lua_settable(L, -3); lua_settable(L, -3);
} }
// Call it // Call it
if(lua_pcall(L, 1, 0, errorhandler)) if (lua_pcall(L, 1, 0, m_errorhandler))
scriptError(); scriptError();
lua_pop(L, 1); // Pop error handler
} }

View File

@ -92,13 +92,10 @@ bool ScriptApiNode::node_on_punch(v3s16 p, MapNode node,
{ {
SCRIPTAPI_PRECHECKHEADER SCRIPTAPI_PRECHECKHEADER
lua_pushcfunction(L, script_error_handler);
int errorhandler = lua_gettop(L);
INodeDefManager *ndef = getServer()->ndef(); INodeDefManager *ndef = getServer()->ndef();
// Push callback function on stack // Push callback function on stack
if(!getItemCallback(ndef->get(node).name.c_str(), "on_punch")) if (!getItemCallback(ndef->get(node).name.c_str(), "on_punch"))
return false; return false;
// Call function // Call function
@ -106,9 +103,8 @@ bool ScriptApiNode::node_on_punch(v3s16 p, MapNode node,
pushnode(L, node, ndef); pushnode(L, node, ndef);
objectrefGetOrCreate(puncher); objectrefGetOrCreate(puncher);
pushPointedThing(pointed); pushPointedThing(pointed);
if(lua_pcall(L, 4, 0, errorhandler)) if (lua_pcall(L, 4, 0, m_errorhandler))
scriptError(); scriptError();
lua_pop(L, 1); // Pop error handler
return true; return true;
} }
@ -117,22 +113,18 @@ bool ScriptApiNode::node_on_dig(v3s16 p, MapNode node,
{ {
SCRIPTAPI_PRECHECKHEADER SCRIPTAPI_PRECHECKHEADER
lua_pushcfunction(L, script_error_handler);
int errorhandler = lua_gettop(L);
INodeDefManager *ndef = getServer()->ndef(); INodeDefManager *ndef = getServer()->ndef();
// Push callback function on stack // Push callback function on stack
if(!getItemCallback(ndef->get(node).name.c_str(), "on_dig")) if (!getItemCallback(ndef->get(node).name.c_str(), "on_dig"))
return false; return false;
// Call function // Call function
push_v3s16(L, p); push_v3s16(L, p);
pushnode(L, node, ndef); pushnode(L, node, ndef);
objectrefGetOrCreate(digger); objectrefGetOrCreate(digger);
if(lua_pcall(L, 3, 0, errorhandler)) if (lua_pcall(L, 3, 0, m_errorhandler))
scriptError(); scriptError();
lua_pop(L, 1); // Pop error handler
return true; return true;
} }
@ -140,82 +132,66 @@ void ScriptApiNode::node_on_construct(v3s16 p, MapNode node)
{ {
SCRIPTAPI_PRECHECKHEADER SCRIPTAPI_PRECHECKHEADER
lua_pushcfunction(L, script_error_handler);
int errorhandler = lua_gettop(L);
INodeDefManager *ndef = getServer()->ndef(); INodeDefManager *ndef = getServer()->ndef();
// Push callback function on stack // Push callback function on stack
if(!getItemCallback(ndef->get(node).name.c_str(), "on_construct")) if (!getItemCallback(ndef->get(node).name.c_str(), "on_construct"))
return; return;
// Call function // Call function
push_v3s16(L, p); push_v3s16(L, p);
if(lua_pcall(L, 1, 0, errorhandler)) if (lua_pcall(L, 1, 0, m_errorhandler))
scriptError(); scriptError();
lua_pop(L, 1); // Pop error handler
} }
void ScriptApiNode::node_on_destruct(v3s16 p, MapNode node) void ScriptApiNode::node_on_destruct(v3s16 p, MapNode node)
{ {
SCRIPTAPI_PRECHECKHEADER SCRIPTAPI_PRECHECKHEADER
lua_pushcfunction(L, script_error_handler);
int errorhandler = lua_gettop(L);
INodeDefManager *ndef = getServer()->ndef(); INodeDefManager *ndef = getServer()->ndef();
// Push callback function on stack // Push callback function on stack
if(!getItemCallback(ndef->get(node).name.c_str(), "on_destruct")) if (!getItemCallback(ndef->get(node).name.c_str(), "on_destruct"))
return; return;
// Call function // Call function
push_v3s16(L, p); push_v3s16(L, p);
if(lua_pcall(L, 1, 0, errorhandler)) if (lua_pcall(L, 1, 0, m_errorhandler))
scriptError(); scriptError();
lua_pop(L, 1); // Pop error handler
} }
void ScriptApiNode::node_after_destruct(v3s16 p, MapNode node) void ScriptApiNode::node_after_destruct(v3s16 p, MapNode node)
{ {
SCRIPTAPI_PRECHECKHEADER SCRIPTAPI_PRECHECKHEADER
lua_pushcfunction(L, script_error_handler);
int errorhandler = lua_gettop(L);
INodeDefManager *ndef = getServer()->ndef(); INodeDefManager *ndef = getServer()->ndef();
// Push callback function on stack // Push callback function on stack
if(!getItemCallback(ndef->get(node).name.c_str(), "after_destruct")) if (!getItemCallback(ndef->get(node).name.c_str(), "after_destruct"))
return; return;
// Call function // Call function
push_v3s16(L, p); push_v3s16(L, p);
pushnode(L, node, ndef); pushnode(L, node, ndef);
if(lua_pcall(L, 2, 0, errorhandler)) if (lua_pcall(L, 2, 0, m_errorhandler))
scriptError(); scriptError();
lua_pop(L, 1); // Pop error handler
} }
bool ScriptApiNode::node_on_timer(v3s16 p, MapNode node, f32 dtime) bool ScriptApiNode::node_on_timer(v3s16 p, MapNode node, f32 dtime)
{ {
SCRIPTAPI_PRECHECKHEADER SCRIPTAPI_PRECHECKHEADER
lua_pushcfunction(L, script_error_handler);
int errorhandler = lua_gettop(L);
INodeDefManager *ndef = getServer()->ndef(); INodeDefManager *ndef = getServer()->ndef();
// Push callback function on stack // Push callback function on stack
if(!getItemCallback(ndef->get(node).name.c_str(), "on_timer")) if (!getItemCallback(ndef->get(node).name.c_str(), "on_timer"))
return false; return false;
// Call function // Call function
push_v3s16(L, p); push_v3s16(L, p);
lua_pushnumber(L,dtime); lua_pushnumber(L,dtime);
if(lua_pcall(L, 2, 1, errorhandler)) if (lua_pcall(L, 2, 1, m_errorhandler))
scriptError(); scriptError();
lua_remove(L, errorhandler); // Remove error handler
return (bool) lua_isboolean(L, -1) && (bool) lua_toboolean(L, -1) == true; return (bool) lua_isboolean(L, -1) && (bool) lua_toboolean(L, -1) == true;
} }
@ -226,63 +202,51 @@ void ScriptApiNode::node_on_receive_fields(v3s16 p,
{ {
SCRIPTAPI_PRECHECKHEADER SCRIPTAPI_PRECHECKHEADER
lua_pushcfunction(L, script_error_handler);
int errorhandler = lua_gettop(L);
INodeDefManager *ndef = getServer()->ndef(); INodeDefManager *ndef = getServer()->ndef();
// If node doesn't exist, we don't know what callback to call // If node doesn't exist, we don't know what callback to call
MapNode node = getEnv()->getMap().getNodeNoEx(p); MapNode node = getEnv()->getMap().getNodeNoEx(p);
if(node.getContent() == CONTENT_IGNORE) if (node.getContent() == CONTENT_IGNORE)
return; return;
// Push callback function on stack // Push callback function on stack
if(!getItemCallback(ndef->get(node).name.c_str(), "on_receive_fields")) if (!getItemCallback(ndef->get(node).name.c_str(), "on_receive_fields"))
return; return;
// Call function // Call function
push_v3s16(L, p); // pos push_v3s16(L, p); // pos
lua_pushstring(L, formname.c_str()); // formname lua_pushstring(L, formname.c_str()); // formname
lua_newtable(L); // fields lua_newtable(L); // fields
for(std::map<std::string, std::string>::const_iterator std::map<std::string, std::string>::const_iterator it;
i = fields.begin(); i != fields.end(); i++){ for (it = fields.begin(); it != fields.end(); it++){
const std::string &name = i->first; const std::string &name = it->first;
const std::string &value = i->second; const std::string &value = it->second;
lua_pushstring(L, name.c_str()); lua_pushstring(L, name.c_str());
lua_pushlstring(L, value.c_str(), value.size()); lua_pushlstring(L, value.c_str(), value.size());
lua_settable(L, -3); lua_settable(L, -3);
} }
objectrefGetOrCreate(sender); // player objectrefGetOrCreate(sender); // player
if(lua_pcall(L, 4, 0, errorhandler)) if (lua_pcall(L, 4, 0, m_errorhandler))
scriptError(); scriptError();
lua_pop(L, 1); // Pop error handler
} }
void ScriptApiNode::node_falling_update(v3s16 p) void ScriptApiNode::node_falling_update(v3s16 p)
{ {
SCRIPTAPI_PRECHECKHEADER SCRIPTAPI_PRECHECKHEADER
lua_pushcfunction(L, script_error_handler);
int errorhandler = lua_gettop(L);
lua_getglobal(L, "nodeupdate"); lua_getglobal(L, "nodeupdate");
push_v3s16(L, p); push_v3s16(L, p);
if(lua_pcall(L, 1, 0, errorhandler)) if (lua_pcall(L, 1, 0, m_errorhandler))
scriptError(); scriptError();
lua_pop(L, 1); // Pop error handler
} }
void ScriptApiNode::node_falling_update_single(v3s16 p) void ScriptApiNode::node_falling_update_single(v3s16 p)
{ {
SCRIPTAPI_PRECHECKHEADER SCRIPTAPI_PRECHECKHEADER
lua_pushcfunction(L, script_error_handler);
int errorhandler = lua_gettop(L);
lua_getglobal(L, "nodeupdate_single"); lua_getglobal(L, "nodeupdate_single");
push_v3s16(L, p); push_v3s16(L, p);
if(lua_pcall(L, 1, 0, errorhandler)) if (lua_pcall(L, 1, 0, m_errorhandler))
scriptError(); scriptError();
lua_pop(L, 1); // Pop error handler
} }

View File

@ -34,19 +34,16 @@ int ScriptApiNodemeta::nodemeta_inventory_AllowMove(v3s16 p,
{ {
SCRIPTAPI_PRECHECKHEADER SCRIPTAPI_PRECHECKHEADER
lua_pushcfunction(L, script_error_handler);
int errorhandler = lua_gettop(L);
INodeDefManager *ndef = getServer()->ndef(); INodeDefManager *ndef = getServer()->ndef();
// If node doesn't exist, we don't know what callback to call // If node doesn't exist, we don't know what callback to call
MapNode node = getEnv()->getMap().getNodeNoEx(p); MapNode node = getEnv()->getMap().getNodeNoEx(p);
if(node.getContent() == CONTENT_IGNORE) if (node.getContent() == CONTENT_IGNORE)
return 0; return 0;
// Push callback function on stack // Push callback function on stack
std::string nodename = ndef->get(node).name; std::string nodename = ndef->get(node).name;
if(!getItemCallback(nodename.c_str(), "allow_metadata_inventory_move")) if (!getItemCallback(nodename.c_str(), "allow_metadata_inventory_move"))
return count; return count;
// function(pos, from_list, from_index, to_list, to_index, count, player) // function(pos, from_list, from_index, to_list, to_index, count, player)
@ -57,10 +54,9 @@ int ScriptApiNodemeta::nodemeta_inventory_AllowMove(v3s16 p,
lua_pushinteger(L, to_index + 1); // to_index lua_pushinteger(L, to_index + 1); // to_index
lua_pushinteger(L, count); // count lua_pushinteger(L, count); // count
objectrefGetOrCreate(player); // player objectrefGetOrCreate(player); // player
if(lua_pcall(L, 7, 1, errorhandler)) if (lua_pcall(L, 7, 1, m_errorhandler))
scriptError(); scriptError();
lua_remove(L, errorhandler); // Remove error handler if (!lua_isnumber(L, -1))
if(!lua_isnumber(L, -1))
throw LuaError("allow_metadata_inventory_move should" throw LuaError("allow_metadata_inventory_move should"
" return a number, guilty node: " + nodename); " return a number, guilty node: " + nodename);
int num = luaL_checkinteger(L, -1); int num = luaL_checkinteger(L, -1);
@ -75,19 +71,16 @@ int ScriptApiNodemeta::nodemeta_inventory_AllowPut(v3s16 p,
{ {
SCRIPTAPI_PRECHECKHEADER SCRIPTAPI_PRECHECKHEADER
lua_pushcfunction(L, script_error_handler);
int errorhandler = lua_gettop(L);
INodeDefManager *ndef = getServer()->ndef(); INodeDefManager *ndef = getServer()->ndef();
// If node doesn't exist, we don't know what callback to call // If node doesn't exist, we don't know what callback to call
MapNode node = getEnv()->getMap().getNodeNoEx(p); MapNode node = getEnv()->getMap().getNodeNoEx(p);
if(node.getContent() == CONTENT_IGNORE) if (node.getContent() == CONTENT_IGNORE)
return 0; return 0;
// Push callback function on stack // Push callback function on stack
std::string nodename = ndef->get(node).name; std::string nodename = ndef->get(node).name;
if(!getItemCallback(nodename.c_str(), "allow_metadata_inventory_put")) if (!getItemCallback(nodename.c_str(), "allow_metadata_inventory_put"))
return stack.count; return stack.count;
// Call function(pos, listname, index, stack, player) // Call function(pos, listname, index, stack, player)
@ -96,9 +89,8 @@ int ScriptApiNodemeta::nodemeta_inventory_AllowPut(v3s16 p,
lua_pushinteger(L, index + 1); // index lua_pushinteger(L, index + 1); // index
LuaItemStack::create(L, stack); // stack LuaItemStack::create(L, stack); // stack
objectrefGetOrCreate(player); // player objectrefGetOrCreate(player); // player
if(lua_pcall(L, 5, 1, errorhandler)) if (lua_pcall(L, 5, 1, m_errorhandler))
scriptError(); scriptError();
lua_remove(L, errorhandler); // Remove error handler
if(!lua_isnumber(L, -1)) if(!lua_isnumber(L, -1))
throw LuaError("allow_metadata_inventory_put should" throw LuaError("allow_metadata_inventory_put should"
" return a number, guilty node: " + nodename); " return a number, guilty node: " + nodename);
@ -114,19 +106,16 @@ int ScriptApiNodemeta::nodemeta_inventory_AllowTake(v3s16 p,
{ {
SCRIPTAPI_PRECHECKHEADER SCRIPTAPI_PRECHECKHEADER
lua_pushcfunction(L, script_error_handler);
int errorhandler = lua_gettop(L);
INodeDefManager *ndef = getServer()->ndef(); INodeDefManager *ndef = getServer()->ndef();
// If node doesn't exist, we don't know what callback to call // If node doesn't exist, we don't know what callback to call
MapNode node = getEnv()->getMap().getNodeNoEx(p); MapNode node = getEnv()->getMap().getNodeNoEx(p);
if(node.getContent() == CONTENT_IGNORE) if (node.getContent() == CONTENT_IGNORE)
return 0; return 0;
// Push callback function on stack // Push callback function on stack
std::string nodename = ndef->get(node).name; std::string nodename = ndef->get(node).name;
if(!getItemCallback(nodename.c_str(), "allow_metadata_inventory_take")) if (!getItemCallback(nodename.c_str(), "allow_metadata_inventory_take"))
return stack.count; return stack.count;
// Call function(pos, listname, index, count, player) // Call function(pos, listname, index, count, player)
@ -135,10 +124,9 @@ int ScriptApiNodemeta::nodemeta_inventory_AllowTake(v3s16 p,
lua_pushinteger(L, index + 1); // index lua_pushinteger(L, index + 1); // index
LuaItemStack::create(L, stack); // stack LuaItemStack::create(L, stack); // stack
objectrefGetOrCreate(player); // player objectrefGetOrCreate(player); // player
if(lua_pcall(L, 5, 1, errorhandler)) if (lua_pcall(L, 5, 1, m_errorhandler))
scriptError(); scriptError();
lua_remove(L, errorhandler); // Remove error handler if (!lua_isnumber(L, -1))
if(!lua_isnumber(L, -1))
throw LuaError("allow_metadata_inventory_take should" throw LuaError("allow_metadata_inventory_take should"
" return a number, guilty node: " + nodename); " return a number, guilty node: " + nodename);
int num = luaL_checkinteger(L, -1); int num = luaL_checkinteger(L, -1);
@ -154,19 +142,16 @@ void ScriptApiNodemeta::nodemeta_inventory_OnMove(v3s16 p,
{ {
SCRIPTAPI_PRECHECKHEADER SCRIPTAPI_PRECHECKHEADER
lua_pushcfunction(L, script_error_handler);
int errorhandler = lua_gettop(L);
INodeDefManager *ndef = getServer()->ndef(); INodeDefManager *ndef = getServer()->ndef();
// If node doesn't exist, we don't know what callback to call // If node doesn't exist, we don't know what callback to call
MapNode node = getEnv()->getMap().getNodeNoEx(p); MapNode node = getEnv()->getMap().getNodeNoEx(p);
if(node.getContent() == CONTENT_IGNORE) if (node.getContent() == CONTENT_IGNORE)
return; return;
// Push callback function on stack // Push callback function on stack
std::string nodename = ndef->get(node).name; std::string nodename = ndef->get(node).name;
if(!getItemCallback(nodename.c_str(), "on_metadata_inventory_move")) if (!getItemCallback(nodename.c_str(), "on_metadata_inventory_move"))
return; return;
// function(pos, from_list, from_index, to_list, to_index, count, player) // function(pos, from_list, from_index, to_list, to_index, count, player)
@ -177,9 +162,8 @@ void ScriptApiNodemeta::nodemeta_inventory_OnMove(v3s16 p,
lua_pushinteger(L, to_index + 1); // to_index lua_pushinteger(L, to_index + 1); // to_index
lua_pushinteger(L, count); // count lua_pushinteger(L, count); // count
objectrefGetOrCreate(player); // player objectrefGetOrCreate(player); // player
if(lua_pcall(L, 7, 0, errorhandler)) if (lua_pcall(L, 7, 0, m_errorhandler))
scriptError(); scriptError();
lua_pop(L, 1); // Pop error handler
} }
// Report put items // Report put items
@ -189,19 +173,16 @@ void ScriptApiNodemeta::nodemeta_inventory_OnPut(v3s16 p,
{ {
SCRIPTAPI_PRECHECKHEADER SCRIPTAPI_PRECHECKHEADER
lua_pushcfunction(L, script_error_handler);
int errorhandler = lua_gettop(L);
INodeDefManager *ndef = getServer()->ndef(); INodeDefManager *ndef = getServer()->ndef();
// If node doesn't exist, we don't know what callback to call // If node doesn't exist, we don't know what callback to call
MapNode node = getEnv()->getMap().getNodeNoEx(p); MapNode node = getEnv()->getMap().getNodeNoEx(p);
if(node.getContent() == CONTENT_IGNORE) if (node.getContent() == CONTENT_IGNORE)
return; return;
// Push callback function on stack // Push callback function on stack
std::string nodename = ndef->get(node).name; std::string nodename = ndef->get(node).name;
if(!getItemCallback(nodename.c_str(), "on_metadata_inventory_put")) if (!getItemCallback(nodename.c_str(), "on_metadata_inventory_put"))
return; return;
// Call function(pos, listname, index, stack, player) // Call function(pos, listname, index, stack, player)
@ -210,9 +191,8 @@ void ScriptApiNodemeta::nodemeta_inventory_OnPut(v3s16 p,
lua_pushinteger(L, index + 1); // index lua_pushinteger(L, index + 1); // index
LuaItemStack::create(L, stack); // stack LuaItemStack::create(L, stack); // stack
objectrefGetOrCreate(player); // player objectrefGetOrCreate(player); // player
if(lua_pcall(L, 5, 0, errorhandler)) if (lua_pcall(L, 5, 0, m_errorhandler))
scriptError(); scriptError();
lua_pop(L, 1); // Pop error handler
} }
// Report taken items // Report taken items
@ -222,19 +202,16 @@ void ScriptApiNodemeta::nodemeta_inventory_OnTake(v3s16 p,
{ {
SCRIPTAPI_PRECHECKHEADER SCRIPTAPI_PRECHECKHEADER
lua_pushcfunction(L, script_error_handler);
int errorhandler = lua_gettop(L);
INodeDefManager *ndef = getServer()->ndef(); INodeDefManager *ndef = getServer()->ndef();
// If node doesn't exist, we don't know what callback to call // If node doesn't exist, we don't know what callback to call
MapNode node = getEnv()->getMap().getNodeNoEx(p); MapNode node = getEnv()->getMap().getNodeNoEx(p);
if(node.getContent() == CONTENT_IGNORE) if (node.getContent() == CONTENT_IGNORE)
return; return;
// Push callback function on stack // Push callback function on stack
std::string nodename = ndef->get(node).name; std::string nodename = ndef->get(node).name;
if(!getItemCallback(nodename.c_str(), "on_metadata_inventory_take")) if (!getItemCallback(nodename.c_str(), "on_metadata_inventory_take"))
return; return;
// Call function(pos, listname, index, stack, player) // Call function(pos, listname, index, stack, player)
@ -243,9 +220,8 @@ void ScriptApiNodemeta::nodemeta_inventory_OnTake(v3s16 p,
lua_pushinteger(L, index + 1); // index lua_pushinteger(L, index + 1); // index
LuaItemStack::create(L, stack); // stack LuaItemStack::create(L, stack); // stack
objectrefGetOrCreate(player); // player objectrefGetOrCreate(player); // player
if(lua_pcall(L, 5, 0, errorhandler)) if (lua_pcall(L, 5, 0, m_errorhandler))
scriptError(); scriptError();
lua_pop(L, 1); // Pop error handler
} }
ScriptApiNodemeta::ScriptApiNodemeta() { ScriptApiNodemeta::ScriptApiNodemeta() {
@ -254,5 +230,3 @@ ScriptApiNodemeta::ScriptApiNodemeta() {
ScriptApiNodemeta::~ScriptApiNodemeta() { ScriptApiNodemeta::~ScriptApiNodemeta() {
} }

View File

@ -27,35 +27,31 @@ bool ScriptApiServer::getAuth(const std::string &playername,
{ {
SCRIPTAPI_PRECHECKHEADER SCRIPTAPI_PRECHECKHEADER
lua_pushcfunction(L, script_error_handler);
int errorhandler = lua_gettop(L);
getAuthHandler(); getAuthHandler();
lua_getfield(L, -1, "get_auth"); lua_getfield(L, -1, "get_auth");
if(lua_type(L, -1) != LUA_TFUNCTION) if (lua_type(L, -1) != LUA_TFUNCTION)
throw LuaError("Authentication handler missing get_auth"); throw LuaError("Authentication handler missing get_auth");
lua_pushstring(L, playername.c_str()); lua_pushstring(L, playername.c_str());
if(lua_pcall(L, 1, 1, errorhandler)) if (lua_pcall(L, 1, 1, m_errorhandler))
scriptError(); scriptError();
lua_remove(L, -2); // Remove auth handler lua_remove(L, -2); // Remove auth handler
lua_remove(L, errorhandler); // Remove error handler
// nil = login not allowed // nil = login not allowed
if(lua_isnil(L, -1)) if (lua_isnil(L, -1))
return false; return false;
luaL_checktype(L, -1, LUA_TTABLE); luaL_checktype(L, -1, LUA_TTABLE);
std::string password; std::string password;
bool found = getstringfield(L, -1, "password", password); bool found = getstringfield(L, -1, "password", password);
if(!found) if (!found)
throw LuaError("Authentication handler didn't return password"); throw LuaError("Authentication handler didn't return password");
if(dst_password) if (dst_password)
*dst_password = password; *dst_password = password;
lua_getfield(L, -1, "privileges"); lua_getfield(L, -1, "privileges");
if(!lua_istable(L, -1)) if (!lua_istable(L, -1))
throw LuaError("Authentication handler didn't return privilege table"); throw LuaError("Authentication handler didn't return privilege table");
if(dst_privs) if (dst_privs)
readPrivileges(-1, *dst_privs); readPrivileges(-1, *dst_privs);
lua_pop(L, 1); lua_pop(L, 1);
@ -68,12 +64,12 @@ void ScriptApiServer::getAuthHandler()
lua_getglobal(L, "minetest"); lua_getglobal(L, "minetest");
lua_getfield(L, -1, "registered_auth_handler"); lua_getfield(L, -1, "registered_auth_handler");
if(lua_isnil(L, -1)){ if (lua_isnil(L, -1)){
lua_pop(L, 1); lua_pop(L, 1);
lua_getfield(L, -1, "builtin_auth_handler"); lua_getfield(L, -1, "builtin_auth_handler");
} }
lua_remove(L, -2); // Remove minetest lua_remove(L, -2); // Remove minetest
if(lua_type(L, -1) != LUA_TTABLE) if (lua_type(L, -1) != LUA_TTABLE)
throw LuaError("Authentication handler table not valid"); throw LuaError("Authentication handler table not valid");
} }
@ -83,13 +79,13 @@ void ScriptApiServer::readPrivileges(int index, std::set<std::string> &result)
result.clear(); result.clear();
lua_pushnil(L); lua_pushnil(L);
if(index < 0) if (index < 0)
index -= 1; index -= 1;
while(lua_next(L, index) != 0){ while (lua_next(L, index) != 0) {
// key at index -2 and value at index -1 // key at index -2 and value at index -1
std::string key = luaL_checkstring(L, -2); std::string key = luaL_checkstring(L, -2);
bool value = lua_toboolean(L, -1); bool value = lua_toboolean(L, -1);
if(value) if (value)
result.insert(key); result.insert(key);
// removes value, keeps key for next iteration // removes value, keeps key for next iteration
lua_pop(L, 1); lua_pop(L, 1);
@ -101,19 +97,15 @@ void ScriptApiServer::createAuth(const std::string &playername,
{ {
SCRIPTAPI_PRECHECKHEADER SCRIPTAPI_PRECHECKHEADER
lua_pushcfunction(L, script_error_handler);
int errorhandler = lua_gettop(L);
getAuthHandler(); getAuthHandler();
lua_getfield(L, -1, "create_auth"); lua_getfield(L, -1, "create_auth");
lua_remove(L, -2); // Remove auth handler lua_remove(L, -2); // Remove auth handler
if(lua_type(L, -1) != LUA_TFUNCTION) if (lua_type(L, -1) != LUA_TFUNCTION)
throw LuaError("Authentication handler missing create_auth"); throw LuaError("Authentication handler missing create_auth");
lua_pushstring(L, playername.c_str()); lua_pushstring(L, playername.c_str());
lua_pushstring(L, password.c_str()); lua_pushstring(L, password.c_str());
if(lua_pcall(L, 2, 0, errorhandler)) if (lua_pcall(L, 2, 0, m_errorhandler))
scriptError(); scriptError();
lua_pop(L, 1); // Pop error handler
} }
bool ScriptApiServer::setPassword(const std::string &playername, bool ScriptApiServer::setPassword(const std::string &playername,
@ -121,19 +113,15 @@ bool ScriptApiServer::setPassword(const std::string &playername,
{ {
SCRIPTAPI_PRECHECKHEADER SCRIPTAPI_PRECHECKHEADER
lua_pushcfunction(L, script_error_handler);
int errorhandler = lua_gettop(L);
getAuthHandler(); getAuthHandler();
lua_getfield(L, -1, "set_password"); lua_getfield(L, -1, "set_password");
lua_remove(L, -2); // Remove auth handler lua_remove(L, -2); // Remove auth handler
if(lua_type(L, -1) != LUA_TFUNCTION) if (lua_type(L, -1) != LUA_TFUNCTION)
throw LuaError("Authentication handler missing set_password"); throw LuaError("Authentication handler missing set_password");
lua_pushstring(L, playername.c_str()); lua_pushstring(L, playername.c_str());
lua_pushstring(L, password.c_str()); lua_pushstring(L, password.c_str());
if(lua_pcall(L, 2, 1, errorhandler)) if (lua_pcall(L, 2, 1, m_errorhandler))
scriptError(); scriptError();
lua_remove(L, -2); // Remove error handler
return lua_toboolean(L, -1); return lua_toboolean(L, -1);
} }