diff --git a/quest_api.lua b/quest_api.lua index 74f0018..042263b 100644 --- a/quest_api.lua +++ b/quest_api.lua @@ -165,9 +165,10 @@ yl_speak_up.input_fs_manage_variables = function(player, formname, fields) return end -- leave this formspec - if(fields and (fields.quit or fields.exit)) then + if(fields and (fields.quit or fields.exit or fields.back)) then local last_fs = yl_speak_up.speak_to[pname][ "working_at" ] yl_speak_up.show_fs(player, last_fs) + return -- add a new variable? elseif(fields and fields.add_variable) then local error_msg = "" @@ -221,13 +222,15 @@ yl_speak_up.input_fs_manage_variables = function(player, formname, fields) false) }) return - -- TODO: delete variable + end + + -- which variable is currently selected? + local var_list = yl_speak_up.get_quest_variables(pname, true) + -- make names of own variables shorter + yl_speak_up.strip_pname_from_varlist(var_list, pname) + table.sort(var_list) -- a var name was selected in the dropdown list - elseif(fields and fields.list_var_names and fields.list_var_names ~= "") then - local var_list = yl_speak_up.get_quest_variables(pname, true) - -- make names of own variables shorter - yl_speak_up.strip_pname_from_varlist(var_list, pname) - table.sort(var_list) + if(fields and fields.list_var_names and fields.list_var_names ~= "") then local index = table.indexof(var_list, fields.list_var_names) if(fields.list_var_names == "Add variable:") then index = 0 @@ -235,6 +238,128 @@ yl_speak_up.input_fs_manage_variables = function(player, formname, fields) if(index and index > -1) then yl_speak_up.speak_to[pname].tmp_index_variable = index + 1 end + end + local var_name = var_list[ yl_speak_up.speak_to[pname].tmp_index_variable ] + + -- revoke read or write access to a variable + if(fields + and ((fields.revoke_player_var_read_access and fields.revoke_player_var_read_access ~= "") + or (fields.revoke_player_var_write_access and fields.revoke_player_var_write_access ~= "")) + and var_name) then + local right = "read" + if(fields.revoke_player_var_write_access and fields.revoke_player_var_write_access ~= "") then + right = "write" + end + -- which player are we talking about? + local selected = yl_speak_up.speak_to[pname]["tmp_index_var_"..right.."_access"] + local pl_with_access = yl_speak_up.get_access_list_for_var(var_name, pname, right.."_access") + local tmp_list = {} + for k, v in pairs(pl_with_access) do + table.insert(tmp_list, k) + end + table.sort(tmp_list) + local grant_to = "" + if(selected > 1) then + grant_to = tmp_list[ selected-1 ] + end + local error_msg = "" + local pl_with_access = yl_speak_up.get_access_list_for_var(var_name, pname, right.."_access") + if(not(grant_to) or grant_to == "") then + error_msg = "For which player do you want to revoke "..right.." access?" + elseif(pname ~= yl_speak_up.npc_owner[ n_id ] + and not(minetest.check_player_privs(pname, {npc_talk_master=true}))) then + error_msg = "Only the owner of the NPC or players with\n".. + "the npc_talk_master priv can change this." + elseif(not(pl_with_access[ grant_to ])) then + error_msg = minetest.formspec_escape(grant_to).." doesn't have "..right.. + " access\nto this variable. Nothing changed." + -- try to revoke access + elseif(not(yl_speak_up.manage_access_to_quest_variable(var_name, pname, grant_to, + right.."_access", nil))) then + error_msg = "An internal error occoured." + else + -- not really an error message here...rather a success message + error_msg = "Revoked "..right.." access to variable\n\"".. + minetest.formspec_escape(var_name).. + "\"\nfor player "..minetest.formspec_escape(grant_to)..".\n".. + "Note: This will *not* affect existing preconditions/effects!" + end + yl_speak_up.show_fs(player, "msg", { + input_to = "yl_speak_up:manage_variables", + formspec = "size[6,2]".. + "label[0.2,0.0;"..error_msg.."]".. + "button[1.5,1.5;2,0.9;back_from_msg;Back]"}) + return + + -- grant read or write access to a variable + elseif(fields + and ((fields.grant_player_var_read_access and fields.grant_player_var_read_access ~= "") + or (fields.grant_player_var_write_access and fields.grant_player_var_write_access ~= "")) + and var_name) then + local right = "read" + if(fields.grant_player_var_write_access and fields.grant_player_var_write_access ~= "") then + right = "write" + end + local grant_to = fields[ "grant_player_var_"..right.."_access"] + local error_msg = "" + local pl_with_access = yl_speak_up.get_access_list_for_var(var_name, pname, right.."_access") + if(pname ~= yl_speak_up.npc_owner[ n_id ] + and not(minetest.check_player_privs(pname, {npc_talk_master=true}))) then + error_msg = "Only the owner of the NPC or players with\n".. + "the npc_talk_master priv can change this." + elseif(grant_to == pname) then + error_msg = "You already have "..right.." access to this variable." + elseif(pl_with_access[ grant_to ]) then + error_msg = minetest.formspec_escape(grant_to).." already has "..right.. + " access\nto this variable." + elseif(not(minetest.check_player_privs(grant_to, {interact=true}))) then + error_msg = "Player \""..minetest.formspec_escape(grant_to).."\" not found." + -- try to grant access + elseif(not(yl_speak_up.manage_access_to_quest_variable(var_name, pname, grant_to, + right.."_access", true))) then + error_msg = "An internal error occoured." + else + -- not really an error message here...rather a success message + error_msg = "Granted "..right.." access to variable\n\"".. + minetest.formspec_escape(var_name).. + "\"\nto player "..minetest.formspec_escape(grant_to).."." + end + yl_speak_up.show_fs(player, "msg", { + input_to = "yl_speak_up:manage_variables", + formspec = "size[6,2]".. + "label[0.2,0.0;"..error_msg.."]".. + "button[1.5,1.5;2,0.9;back_from_msg;Back]"}) + return + + -- the player clicked on a name in the list of players with read or write access + elseif(fields + and ((fields.list_var_read_access and fields.list_var_read_access ~= "") + or (fields.list_var_write_access and fields.list_var_write_access ~= "")) + and var_name) then + local right = "read" + if(fields.list_var_write_access and fields.list_var_write_access ~= "") then + right = "write" + end + local selected = fields[ "list_var_"..right.."_access"] + local pl_with_access = yl_speak_up.get_access_list_for_var(var_name, pname, right.."_access") + local tmp_list = {} + for k, v in pairs(pl_with_access) do + table.insert(tmp_list, k) + end + table.sort(tmp_list) + local index = table.indexof(tmp_list, selected) + if(selected == "Add player:") then + index = 0 + end + if(index and index > -1) then + yl_speak_up.speak_to[pname]["tmp_index_var_"..right.."_access"] = index + 1 + end + yl_speak_up.show_fs(player, "manage_variables") + return + + -- TODO: delete variable + -- a var name was selected in the dropdown list + elseif(fields and fields.list_var_names and fields.list_var_names ~= "") then -- show the same formspec again, with a diffrent variable selected yl_speak_up.show_fs(player, "manage_variables") return @@ -268,6 +393,9 @@ yl_speak_up.get_fs_manage_variables = function(player, param) "tooltip[add_variable;Create a new varialbe with the name\n".. "you entered in the field to the left.]" else + local k = var_list[ yl_speak_up.speak_to[pname].tmp_index_variable ] + local pl_with_read_access = yl_speak_up.get_access_list_for_var(k, pname, "read_access") + local pl_with_write_access = yl_speak_up.get_access_list_for_var(k, pname, "write_access") local add_read_button = "" local add_write_button = "" if(not(yl_speak_up.speak_to[pname].tmp_index_var_read_access) @@ -291,7 +419,8 @@ yl_speak_up.get_fs_manage_variables = function(player, param) -- offer a dropdown list and a text input field for new varialbe names for adding "label[0.2,3.05;Players with read access to this variable:]".. yl_speak_up.create_dropdown_playerlist(player, pname, - {}, yl_speak_up.speak_to[pname].tmp_index_var_read_access, -- TODO + pl_with_read_access, + yl_speak_up.speak_to[pname].tmp_index_var_read_access, 5.5, 2.9, 0.0, "list_var_read_access", "player", "Remove player from list", "grant_player_var_read_access", "Enter the name of the player that shall\n".. @@ -303,7 +432,8 @@ yl_speak_up.get_fs_manage_variables = function(player, param) )..add_read_button.. "label[0.2,4.05;Players with *write* access to this variable:]".. yl_speak_up.create_dropdown_playerlist(player, pname, - {}, yl_speak_up.speak_to[pname].tmp_index_var_write_access, -- TODO + pl_with_write_access, + yl_speak_up.speak_to[pname].tmp_index_var_write_access, 5.5, 3.9, 0.0, "list_var_write_access", "player", "Remove player from list", "grant_player_var_write_access", "Enter the name of the player that shall\n".. @@ -404,6 +534,59 @@ yl_speak_up.get_pname_for_n_id = function(n_id) end +-- add or revoke read or write access to a variable +-- +-- k: name of the variable +-- pname: the name of the player trying to grant or revoke the right +-- grant_to_pname: the name of the player who shall have that access right +-- grant_write_access: +-- if false: grant read access +-- if true: grant write access +-- do_grant: +-- if false: revoke acces +-- if true: grant access +-- returns true if the variable was found +yl_speak_up.manage_access_to_quest_variable = function(k, pname, grant_to_pname, what_to_grant, do_grant) + k = yl_speak_up.add_pname_to_var(k, pname) + -- grant or revoke priv + if(not(do_grant)) then + do_grant = nil + end + -- only read and write access can be granted + if(not(what_to_grant) or (what_to_grant ~= "read_access" and what_to_grant ~= "write_access")) then + return false + end + -- the variable needs to exist + if(not(yl_speak_up.player_vars[ k ])) then + return false + end + -- make sure all the necessary tables exist + if(not(yl_speak_up.player_vars[ k ][ "$META$" ])) then + yl_speak_up.player_vars[ k ][ "$META$"] = { what_to_grant = {} } + end + if(not(yl_speak_up.player_vars[ k ][ "$META$" ][ what_to_grant ])) then + yl_speak_up.player_vars[ k ][ "$META$" ][ what_to_grant ] = {} + end + yl_speak_up.player_vars[ k ][ "$META$"][ what_to_grant ][ grant_to_pname ] = do_grant + yl_speak_up.save_quest_variables(true) + return true +end + + +-- get a list of all players who have read or write access to variable k (belonging to pname) +-- (technically a table and not a list) +yl_speak_up.get_access_list_for_var = function(k, pname, access_what) + k = yl_speak_up.add_pname_to_var(k, pname) + if(not(k) + or not(yl_speak_up.player_vars[ k ]) + or not(yl_speak_up.player_vars[ k ][ "$META$"]) + or not(yl_speak_up.player_vars[ k ][ "$META$"][ access_what ])) then + return {} + end + return yl_speak_up.player_vars[ k ][ "$META$"][ access_what ] +end + + -- the dialog data of an NPC is saved - use this to save some statistical data -- plus store which variables are used by this NPC -- TODO: show this data in a formspec to admins for maintenance