-- the privs players need some privs -- npc_talk_owner is required to set up an NPC; -- npc_talk_master allows to edit NPC of other players; -- npc_master allows to set dangerous commands like execute lua code local npc_master_priv_definition = { description="Can use the staffs to command NPCs", give_to_singleplayer = false, give_to_admin = true, } minetest.register_privilege("npc_master", npc_master_priv_definition) local npc_talk_owner_priv_definition = { description="Can edit the dialogs of his/her own NPCs", give_to_singleplayer = false, give_to_admin = true, } minetest.register_privilege("npc_talk_owner", npc_talk_owner_priv_definition) local npc_talk_master_priv_definition = { description="Can edit the dialogs of NPCs independent of owner", give_to_singleplayer = false, give_to_admin = true, } minetest.register_privilege("npc_talk_master", npc_talk_master_priv_definition) -- NPC also need privs to execute more dangerous commands -- this table will hold the actual privs in the form of -- indices of the form t[][] = True yl_speak_up.npc_priv_table = {} -- where shall the privs be stored so that they will be available after server restart? yl_speak_up.npc_priv_path = minetest.get_worldpath().."/yl_speak_up_npc_privs.data" -- these are deemed dangerous and checked yl_speak_up.npc_priv_names = { "precon_exec_lua", "effect_exec_lua", "effect_give_item", "effect_take_item", "effect_move_player", } yl_speak_up.npc_has_priv = function(n_id, priv_name) -- fallback: disallow if(not(n_id) or not(priv_name)) then return false end if(not(yl_speak_up.npc_priv_table[n_id]) or not(yl_speak_up.npc_priv_table[n_id][priv_name])) then minetest.log( "action", "[MOD] yl_speak_up: NPC with ID "..tostring(n_id).. " was denied the NPC priv "..tostring(priv_name)..".") return false end return true end yl_speak_up.npc_privs_load = function() local file,err = io.open( yl_speak_up.npc_priv_path, "rb") if (file == nil) then yl_speak_up.npc_priv_table = {} return end local data = file:read("*all") file:close() yl_speak_up.npc_priv_table = minetest.deserialize(data) end yl_speak_up.npc_privs_store = function() local file,err = io.open( yl_speak_up.npc_priv_path, "wb") if (file == nil) then return end file:write(minetest.serialize(yl_speak_up.npc_priv_table)) file:close() end -- a chat command to grant or deny or disallow npc these privs; -- it is not checked if the NPC exists minetest.register_chatcommand( 'npc_talk_privs', { description = "Grants or revokes the privilege to the ".. "yl_speak_up-NPC with the ID .\n".. "Call: [grant|revoke] \n".. "If called with parameter [list], all granted privs for all NPC are shown.", privs = {privs = true}, func = function(pname, param) if(not(param) or param == "") then minetest.chat_send_player(pname, "Usage: [grant|revoke|list] \n".. "The following privilege exist:\n\t".. table.concat(yl_speak_up.npc_priv_names, ", ")..".") return end local parts = string.split(param, " ") if(parts[1] == "list") then local text = "This list contains the privs of each NPC in the form of ".. ": " -- create list of all existing extra privs for npc for n_id, v in pairs(yl_speak_up.npc_priv_table) do text = text..".\n"..tostring(n_id)..":" local found = false for priv, w in pairs(v) do text = text.." "..tostring(priv) found = true end if(not(found)) then text = text.." " end end minetest.chat_send_player(pname, text..".") return end if((parts[1] ~= "grant" and parts[1] ~= "revoke") or #parts ~= 3) then minetest.chat_send_player(pname, "Usage: [grant|revoke] ") return end local command = parts[1] local n_id = parts[2] local priv = parts[3] if(table.indexof(yl_speak_up.npc_priv_names, priv) == -1) then minetest.chat_send_player(pname, "Unknown priv \""..tostring(priv).."\".\n".. "The following privilege exist:\n\t".. table.concat(yl_speak_up.npc_priv_names, ", ")..".") return end if(command == "grant" and not(yl_speak_up.npc_priv_table[n_id])) then yl_speak_up.npc_priv_table[n_id] = {} end if(command == "grant") then yl_speak_up.npc_priv_table[n_id][priv] = true elseif(yl_speak_up.npc_priv_table[n_id]) then yl_speak_up.npc_priv_table[n_id][priv] = nil end local text = "New privs of NPC "..tostring(n_id)..":" local found = false if(yl_speak_up.npc_priv_table[n_id]) then for k, v in pairs(yl_speak_up.npc_priv_table[n_id]) do text = text.." "..tostring(k) found = true end end if(not(found)) then text = text.." " yl_speak_up.npc_priv_table[n_id] = nil end minetest.chat_send_player(pname, text..".") yl_speak_up.npc_privs_store() end }) -- when the game is started: load the npc privs yl_speak_up.npc_privs_load()