bool ScriptApiEntity::luaentity_on_death(u16 id, ServerActiveObject *killer) { SCRIPTAPI_PRECHECKHEADER int error_handler = PUSH_ERROR_HANDLER(L); // Get core.luaentities[id] luaentity_get(L, id); int object = lua_gettop(L); // State: object is at top of stack // Get function lua_getfield(L, -1, "on_death"); if (lua_isnil(L, -1)) { lua_pop(L, 2); // Pop on_death and entity return false; } luaL_checktype(L, -1, LUA_TFUNCTION); lua_pushvalue(L, object); // self objectrefGetOrCreate(L, killer); // killer reference setOriginFromTable(object); PCALL_RES(lua_pcall(L, 2, 1, error_handler)); bool retval = lua_toboolean(L, -1); lua_pop(L, 2); // Pop object and error handler return retval; }
void ScriptApiEntity::luaentity_Activate(u16 id, const std::string &staticdata, u32 dtime_s) { SCRIPTAPI_PRECHECKHEADER 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); // Get on_activate function lua_getfield(L, -1, "on_activate"); 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); setOriginFromTable(object); PCALL_RES(lua_pcall(L, 3, 0, error_handler)); } else { lua_pop(L, 1); } lua_pop(L, 2); // Pop object and error handler }
// Calls entity:on_rightclick(ObjectRef clicker) void ScriptApiEntity::luaentity_Rightclick(u16 id, ServerActiveObject *clicker) { SCRIPTAPI_PRECHECKHEADER //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); // State: object is at top of stack // Get function lua_getfield(L, -1, "on_rightclick"); if (lua_isnil(L, -1)) { lua_pop(L, 2); // Pop on_rightclick and entity return; } luaL_checktype(L, -1, LUA_TFUNCTION); lua_pushvalue(L, object); // self objectrefGetOrCreate(L, clicker); // Clicker reference setOriginFromTable(object); PCALL_RES(lua_pcall(L, 2, 0, error_handler)); lua_pop(L, 2); // Pop object and error handler }
void AsyncEngine::step(lua_State *L) { int error_handler = PUSH_ERROR_HANDLER(L); lua_getglobal(L, "core"); resultQueueMutex.lock(); while (!resultQueue.empty()) { LuaJobInfo jobDone = resultQueue.front(); resultQueue.pop_front(); lua_getfield(L, -1, "async_event_handler"); if (lua_isnil(L, -1)) { FATAL_ERROR("Async event handler does not exist!"); } luaL_checktype(L, -1, LUA_TFUNCTION); lua_pushinteger(L, jobDone.id); lua_pushlstring(L, jobDone.serializedResult.data(), jobDone.serializedResult.size()); PCALL_RESL(L, lua_pcall(L, 2, 0, error_handler)); } resultQueueMutex.unlock(); lua_pop(L, 2); // Pop core and 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"); lua_remove(L, -2); // Remove core if (lua_isnil(L, -1)) { lua_pop(L, 1); // Pop button handler return; } luaL_checktype(L, -1, LUA_TFUNCTION); // Convert fields to a Lua table lua_newtable(L); StringMap::const_iterator it; for (it = fields.begin(); it != fields.end(); ++it) { const std::string &name = it->first; const std::string &value = it->second; lua_pushstring(L, name.c_str()); lua_pushlstring(L, value.c_str(), value.size()); lua_settable(L, -3); } // Call it PCALL_RES(lua_pcall(L, 1, 0, error_handler)); lua_pop(L, 1); // Pop error handler }
std::string ScriptApiEntity::luaentity_GetStaticdata(u16 id) { SCRIPTAPI_PRECHECKHEADER //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); // Get get_staticdata function lua_getfield(L, -1, "get_staticdata"); if (lua_isnil(L, -1)) { lua_pop(L, 2); // Pop entity and get_staticdata return ""; } luaL_checktype(L, -1, LUA_TFUNCTION); lua_pushvalue(L, object); // self setOriginFromTable(object); PCALL_RES(lua_pcall(L, 1, 1, error_handler)); lua_remove(L, object); lua_remove(L, error_handler); size_t len = 0; const char *s = lua_tolstring(L, -1, &len); lua_pop(L, 1); // Pop static data return std::string(s, len); }
// add_item(pos, itemstack or itemstring or table) -> ObjectRef or nil // pos = {x=num, y=num, z=num} int ModApiEnvMod::l_add_item(lua_State *L) { GET_ENV_PTR; // pos //v3f pos = checkFloatPos(L, 1); // item ItemStack item = read_item(L, 2,getServer(L)->idef()); if(item.empty() || !item.isKnown(getServer(L)->idef())) return 0; int error_handler = PUSH_ERROR_HANDLER(L); // Use spawn_item to spawn a __builtin:item lua_getglobal(L, "core"); lua_getfield(L, -1, "spawn_item"); lua_remove(L, -2); // Remove core if(lua_isnil(L, -1)) return 0; lua_pushvalue(L, 1); lua_pushstring(L, item.getItemString().c_str()); PCALL_RESL(L, lua_pcall(L, 2, 1, error_handler)); lua_remove(L, error_handler); return 1; }
// Return number of accepted items to be moved int ScriptApiDetached::detached_inventory_AllowMove( const std::string &name, const std::string &from_list, int from_index, const std::string &to_list, int to_index, int count, ServerActiveObject *player) { SCRIPTAPI_PRECHECKHEADER int error_handler = PUSH_ERROR_HANDLER(L); // Push callback function on stack if (!getDetachedInventoryCallback(name, "allow_move")) return count; // function(inv, from_list, from_index, to_list, to_index, count, player) // inv InventoryLocation loc; loc.setDetached(name); InvRef::create(L, loc); 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(L, player); // player 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, 2); // Pop integer and error handler return ret; }
// Return number of accepted items to be taken int ScriptApiDetached::detached_inventory_AllowTake( const std::string &name, const std::string &listname, int index, ItemStack &stack, ServerActiveObject *player) { 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 // Call function(inv, listname, index, stack, player) InventoryLocation loc; loc.setDetached(name); InvRef::create(L, loc); // inv lua_pushstring(L, listname.c_str()); // listname lua_pushinteger(L, index + 1); // index LuaItemStack::create(L, stack); // stack objectrefGetOrCreate(L, player); // player 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, 2); // Pop integer and error handler return ret; }
// Report moved items void ScriptApiDetached::detached_inventory_OnMove( const std::string &name, const std::string &from_list, int from_index, const std::string &to_list, int to_index, int count, ServerActiveObject *player) { SCRIPTAPI_PRECHECKHEADER int error_handler = PUSH_ERROR_HANDLER(L); // Push callback function on stack if (!getDetachedInventoryCallback(name, "on_move")) return; // function(inv, from_list, from_index, to_list, to_index, count, player) // inv InventoryLocation loc; loc.setDetached(name); InvRef::create(L, loc); 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(L, player); // player PCALL_RES(lua_pcall(L, 7, 0, error_handler)); lua_pop(L, 1); // Pop error handler }
// Report taken items void ScriptApiDetached::detached_inventory_OnTake( const std::string &name, const std::string &listname, int index, ItemStack &stack, ServerActiveObject *player) { SCRIPTAPI_PRECHECKHEADER int error_handler = PUSH_ERROR_HANDLER(L); // Push callback function on stack if (!getDetachedInventoryCallback(name, "on_take")) return; // Call function(inv, listname, index, stack, player) // inv InventoryLocation loc; loc.setDetached(name); InvRef::create(L, loc); lua_pushstring(L, listname.c_str()); // listname lua_pushinteger(L, index + 1); // index LuaItemStack::create(L, stack); // stack objectrefGetOrCreate(L, player); // player PCALL_RES(lua_pcall(L, 5, 0, error_handler)); lua_pop(L, 1); // Pop error handler }
// Return number of accepted items to be put int ScriptApiNodemeta::nodemeta_inventory_AllowPut(v3s16 p, const std::string &listname, int index, ItemStack &stack, ServerActiveObject *player) { 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 MapNode node = getEnv()->getMap().getNodeNoEx(p); if (node.getContent() == CONTENT_IGNORE) return 0; // Push callback function on stack std::string nodename = ndef->get(node).name; if (!getItemCallback(nodename.c_str(), "allow_metadata_inventory_put", &p)) return stack.count; // Call function(pos, listname, index, stack, player) push_v3s16(L, p); // pos lua_pushstring(L, listname.c_str()); // listname lua_pushinteger(L, index + 1); // index LuaItemStack::create(L, stack); // stack objectrefGetOrCreate(L, player); // player 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, 2); // Pop integer and error handler return num; }
// Report taken items void ScriptApiNodemeta::nodemeta_inventory_OnTake(v3s16 p, const std::string &listname, int index, ItemStack &stack, ServerActiveObject *player) { 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 MapNode node = getEnv()->getMap().getNodeNoEx(p); if (node.getContent() == CONTENT_IGNORE) return; // Push callback function on stack std::string nodename = ndef->get(node).name; if (!getItemCallback(nodename.c_str(), "on_metadata_inventory_take", &p)) return; // Call function(pos, listname, index, stack, player) push_v3s16(L, p); // pos lua_pushstring(L, listname.c_str()); // listname lua_pushinteger(L, index + 1); // index LuaItemStack::create(L, stack); // stack objectrefGetOrCreate(L, player); // player PCALL_RES(lua_pcall(L, 5, 0, error_handler)); lua_pop(L, 1); // Pop error handler }
// Report moved items void ScriptApiNodemeta::nodemeta_inventory_OnMove(v3s16 p, const std::string &from_list, int from_index, const std::string &to_list, int to_index, int count, ServerActiveObject *player) { 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 MapNode node = getEnv()->getMap().getNodeNoEx(p); if (node.getContent() == CONTENT_IGNORE) return; // Push callback function on stack std::string nodename = ndef->get(node).name; if (!getItemCallback(nodename.c_str(), "on_metadata_inventory_move", &p)) return; // function(pos, from_list, from_index, to_list, to_index, count, player) 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(L, player); // player PCALL_RES(lua_pcall(L, 7, 0, error_handler)); lua_pop(L, 1); // Pop error handler }
// Calls entity:on_punch(ObjectRef puncher, time_from_last_punch, // tool_capabilities, direction, damage) bool ScriptApiEntity::luaentity_Punch(u16 id, ServerActiveObject *puncher, float time_from_last_punch, const ToolCapabilities *toolcap, v3f dir, s16 damage) { SCRIPTAPI_PRECHECKHEADER //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); // State: object is at top of stack // Get function lua_getfield(L, -1, "on_punch"); if (lua_isnil(L, -1)) { lua_pop(L, 2); // Pop on_punch and entity return false; } luaL_checktype(L, -1, LUA_TFUNCTION); lua_pushvalue(L, object); // self objectrefGetOrCreate(L, puncher); // Clicker reference lua_pushnumber(L, time_from_last_punch); push_tool_capabilities(L, *toolcap); push_v3f(L, dir); lua_pushnumber(L, damage); setOriginFromTable(object); PCALL_RES(lua_pcall(L, 6, 1, error_handler)); bool retval = lua_toboolean(L, -1); lua_pop(L, 2); // Pop object and error handler return retval; }
bool ScriptApiItem::item_CraftPredict(ItemStack &item, ServerActiveObject *user, const InventoryList *old_craft_grid, const InventoryLocation &craft_inv) { SCRIPTAPI_PRECHECKHEADER int error_handler = PUSH_ERROR_HANDLER(L); lua_getglobal(L, "core"); lua_getfield(L, -1, "craft_predict"); LuaItemStack::create(L, item); objectrefGetOrCreate(L, user); //Push inventory list std::vector<ItemStack> items; for (u32 i = 0; i < old_craft_grid->getSize(); i++) { items.push_back(old_craft_grid->getItem(i)); } push_items(L, items); InvRef::create(L, craft_inv); PCALL_RES(lua_pcall(L, 4, 1, error_handler)); if (!lua_isnil(L, -1)) { try { item = read_item(L,-1, getServer()); } catch (LuaError &e) { throw LuaError(std::string(e.what()) + ". item=" + item.name); } } lua_pop(L, 2); // Pop item and error handler return true; }
void ScriptApiEntity::luaentity_Step(u16 id, float dtime) { SCRIPTAPI_PRECHECKHEADER //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); // State: object is at top of stack // Get step function lua_getfield(L, -1, "on_step"); if (lua_isnil(L, -1)) { lua_pop(L, 2); // Pop on_step and entity return; } luaL_checktype(L, -1, LUA_TFUNCTION); lua_pushvalue(L, object); // self lua_pushnumber(L, dtime); // dtime setOriginFromTable(object); PCALL_RES(lua_pcall(L, 2, 0, error_handler)); lua_pop(L, 2); // Pop object and error handler }
bool ScriptApiItem::item_OnUse(ItemStack &item, ServerActiveObject *user, const PointedThing &pointed) { SCRIPTAPI_PRECHECKHEADER int error_handler = PUSH_ERROR_HANDLER(L); // Push callback function on stack if (!getItemCallback(item.name.c_str(), "on_use")) return false; // Call function LuaItemStack::create(L, item); objectrefGetOrCreate(L, user); pushPointedThing(pointed); PCALL_RES(lua_pcall(L, 3, 1, error_handler)); if(!lua_isnil(L, -1)) { try { item = read_item(L,-1, getServer()); } catch (LuaError &e) { throw LuaError(std::string(e.what()) + ". item=" + item.name); } } lua_pop(L, 2); // Pop item and error handler return true; }
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, error_handler)); lua_pop(L, 1); // Pop error handler }
void LuaABM::trigger(ServerEnvironment *env, v3s16 p, MapNode n, u32 active_object_count, u32 active_object_count_wider, MapNode neighbor, bool activate) { GameScripting *scriptIface = env->getScriptIface(); auto _script_lock = RecursiveMutexAutoLock(scriptIface->m_luastackmutex, std::try_to_lock); if (!_script_lock.owns_lock()) { return; } scriptIface->realityCheck(); lua_State *L = scriptIface->getStack(); sanity_check(lua_checkstack(L, 20)); StackUnroller stack_unroller(L); int error_handler = PUSH_ERROR_HANDLER(L); // Get registered_abms lua_getglobal(L, "core"); lua_getfield(L, -1, "registered_abms"); luaL_checktype(L, -1, LUA_TTABLE); lua_remove(L, -2); // Remove core // Get registered_abms[m_id] lua_pushnumber(L, m_id); lua_gettable(L, -2); if(lua_isnil(L, -1)) //FATAL_ERROR(""); return; lua_remove(L, -2); // Remove registered_abms scriptIface->setOriginFromTable(-1); // Call action luaL_checktype(L, -1, LUA_TTABLE); lua_getfield(L, -1, "action"); luaL_checktype(L, -1, LUA_TFUNCTION); lua_remove(L, -2); // Remove registered_abms[m_id] push_v3s16(L, p); pushnode(L, n, env->getGameDef()->ndef()); lua_pushnumber(L, active_object_count); lua_pushnumber(L, active_object_count_wider); pushnode(L, neighbor, env->getGameDef()->ndef()); lua_pushboolean(L, activate); int result = lua_pcall(L, 6, 0, error_handler); if (result) scriptIface->scriptError(result, "LuaABM::trigger"); lua_pop(L, 1); // Pop error handler }
void ScriptApiServer::createAuth(const std::string &playername, const std::string &password) { SCRIPTAPI_PRECHECKHEADER int error_handler = PUSH_ERROR_HANDLER(L); getAuthHandler(); lua_getfield(L, -1, "create_auth"); lua_remove(L, -2); // Remove auth handler if (lua_type(L, -1) != LUA_TFUNCTION) 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, error_handler)); lua_pop(L, 1); // Pop error handler }
void LuaLBM::trigger(ServerEnvironment *env, v3s16 p, MapNode n) { GameScripting *scriptIface = env->getScriptIface(); auto _script_lock = RecursiveMutexAutoLock(scriptIface->m_luastackmutex, std::try_to_lock); if (!_script_lock.owns_lock()) { return; } scriptIface->realityCheck(); lua_State *L = scriptIface->getStack(); sanity_check(lua_checkstack(L, 20)); StackUnroller stack_unroller(L); int error_handler = PUSH_ERROR_HANDLER(L); // Get registered_lbms lua_getglobal(L, "core"); lua_getfield(L, -1, "registered_lbms"); luaL_checktype(L, -1, LUA_TTABLE); lua_remove(L, -2); // Remove core // Get registered_lbms[m_id] lua_pushnumber(L, m_id); lua_gettable(L, -2); //FATAL_ERROR_IF(lua_isnil(L, -1), "Entry with given id not found in registered_lbms table"); if (lua_isnil(L, -1)) { errorstream << "Entry with given id " << m_id << " not found in registered_lbms table" << std::endl; return; } lua_remove(L, -2); // Remove registered_lbms scriptIface->setOriginFromTable(-1); // Call action luaL_checktype(L, -1, LUA_TTABLE); lua_getfield(L, -1, "action"); luaL_checktype(L, -1, LUA_TFUNCTION); lua_remove(L, -2); // Remove registered_lbms[m_id] push_v3s16(L, p); pushnode(L, n, env->getGameDef()->ndef()); int result = lua_pcall(L, 2, 0, error_handler); if (result) scriptIface->scriptError(result, "LuaLBM::trigger"); 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 if (!getItemCallback(ndef->get(node).name.c_str(), "on_destruct")) return; // Call function push_v3s16(L, p); PCALL_RES(lua_pcall(L, 1, 0, error_handler)); lua_pop(L, 1); // Pop error handler }
bool ScriptApiServer::setPassword(const std::string &playername, const std::string &password) { SCRIPTAPI_PRECHECKHEADER int error_handler = PUSH_ERROR_HANDLER(L); getAuthHandler(); lua_getfield(L, -1, "set_password"); lua_remove(L, -2); // Remove auth handler if (lua_type(L, -1) != LUA_TFUNCTION) 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, error_handler)); lua_remove(L, error_handler); return lua_toboolean(L, -1); }
s16 ScriptApiPlayer::on_player_hpchange(ServerActiveObject *player, s16 hp_change) { 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"); lua_remove(L, -2); objectrefGetOrCreate(L, player); lua_pushnumber(L, hp_change); PCALL_RES(lua_pcall(L, 2, 1, error_handler)); hp_change = lua_tointeger(L, -1); lua_pop(L, 2); // Pop result and error handler return hp_change; }
void LuaABM::trigger(ServerEnvironment *env, v3s16 p, MapNode n, u32 active_object_count, u32 active_object_count_wider) { ServerScripting *scriptIface = env->getScriptIface(); scriptIface->realityCheck(); lua_State *L = scriptIface->getStack(); sanity_check(lua_checkstack(L, 20)); StackUnroller stack_unroller(L); int error_handler = PUSH_ERROR_HANDLER(L); // Get registered_abms lua_getglobal(L, "core"); lua_getfield(L, -1, "registered_abms"); luaL_checktype(L, -1, LUA_TTABLE); lua_remove(L, -2); // Remove core // Get registered_abms[m_id] lua_pushnumber(L, m_id); lua_gettable(L, -2); if(lua_isnil(L, -1)) FATAL_ERROR(""); lua_remove(L, -2); // Remove registered_abms scriptIface->setOriginFromTable(-1); // Call action luaL_checktype(L, -1, LUA_TTABLE); lua_getfield(L, -1, "action"); luaL_checktype(L, -1, LUA_TFUNCTION); lua_remove(L, -2); // Remove registered_abms[m_id] push_v3s16(L, p); pushnode(L, n, env->getGameDef()->ndef()); lua_pushnumber(L, active_object_count); lua_pushnumber(L, active_object_count_wider); int result = lua_pcall(L, 4, 0, error_handler); if (result) scriptIface->scriptError(result, "LuaABM::trigger"); 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 if (!getItemCallback(ndef->get(node).name.c_str(), "on_timer")) return false; // Call function push_v3s16(L, p); lua_pushnumber(L,dtime); 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; }
bool ScriptApiNode::node_on_dig(v3s16 p, MapNode node, ServerActiveObject *digger) { SCRIPTAPI_PRECHECKHEADER int error_handler = PUSH_ERROR_HANDLER(L); INodeDefManager *ndef = getServer()->ndef(); // Push callback function on stack if (!getItemCallback(ndef->get(node).name.c_str(), "on_dig")) return false; // Call function push_v3s16(L, p); pushnode(L, node, ndef); objectrefGetOrCreate(L, digger); PCALL_RES(lua_pcall(L, 3, 0, error_handler)); lua_pop(L, 1); // Pop error handler return true; }
void ScriptApiMainMenu::handleMainMenuEvent(std::string text) { SCRIPTAPI_PRECHECKHEADER int error_handler = PUSH_ERROR_HANDLER(L); // Get handler function lua_getglobal(L, "core"); lua_getfield(L, -1, "event_handler"); lua_remove(L, -2); // Remove core 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()); PCALL_RES(lua_pcall(L, 1, 0, error_handler)); lua_pop(L, 1); // Pop error handler }
bool ScriptApiServer::getAuth(const std::string &playername, std::string *dst_password, std::set<std::string> *dst_privs) { 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, error_handler)); lua_remove(L, -2); // Remove auth handler lua_remove(L, error_handler); // nil = login not allowed if (lua_isnil(L, -1)) return false; luaL_checktype(L, -1, LUA_TTABLE); std::string password; bool found = getstringfield(L, -1, "password", password); if (!found) throw LuaError("Authentication handler didn't return password"); if (dst_password) *dst_password = password; lua_getfield(L, -1, "privileges"); if (!lua_istable(L, -1)) throw LuaError("Authentication handler didn't return privilege table"); if (dst_privs) readPrivileges(-1, *dst_privs); lua_pop(L, 1); return true; }