From 1f7aa8c229c53c462217bdbcaec4c82c13725bbd Mon Sep 17 00:00:00 2001 From: Hendrik Langer Date: Wed, 27 May 2020 13:10:41 +0200 Subject: [PATCH] redo area and privilege calculation --- init.lua | 91 +++++++++++++++++++++------------------------------ mod_areas.lua | 2 +- player.lua | 5 ++- region.lua | 22 +++++++++---- 4 files changed, 56 insertions(+), 64 deletions(-) diff --git a/init.lua b/init.lua index 3ca46c3..05ef7be 100644 --- a/init.lua +++ b/init.lua @@ -23,49 +23,37 @@ function creative_regions:update_player(player) local pmeta = player:get_meta() -- pmeta:mark_as_private("creative_regions.active_regions") - local player_last_active_regions = pmeta:get_string("creative_regions.active_regions") or "-1" - local player_active_regions = "-1" + + local current_regions_size = {} + local player_active_region_str = "" local areas_owner = false local areas_guest = false local areas_open = false - local smallest_region = {} - local smallest_areas_area = {} + -- skip for players with protection_bypass if minetest.check_player_privs(name, { protection_bypass=true }) then - --minetest.chat_send_player(name, "Changed region. You have protection_bypass priv") return end - -- enter region + -- find active regions local current_regions = self.astore:get_areas_for_pos(pos, true, true) for astore_id, astore_area in pairs( current_areas ) do - local regionsize = creative_regions:get_region_size(astore_area) - if not smallest_region.size or regionsize < smallest_region.size then - smallest_region.id = tostring(astore_id) - smallest_region.size = regionsize - end - end - if smallest_region.id then - player_active_regions = tostring(smallest_region.id) + local id = "r"..tostring(astore_id) + local size = creative_regions:get_region_size(astore_area) + table.insert(current_regions_size, { ["id"]=id, ["size"]=size }) end - -- enter areas mod area - local a_current_areas = {} + -- find active areas from areas mod if minetest.get_modpath("areas") then - a_current_areas = areas:getAreasAtPos(pos) - for a_id, a_area in pairs( a_current_areas ) do - local areasize = creative_regions:get_areas_area_size(a_area) - if not smallest_areas_area.size or areasize < smallest_areas_area.size then - smallest_areas_area.id = tostring(a_id) - smallest_areas_area.size = areasize - end - player_active_areas = player_active_areas .. ", a"..a_id - if a_area.owner == name then + local current_areas = areas:getAreasAtPos(pos) + for areas_id, areas_area in pairs( current_areas ) do + local id = "a"..tostring(areas_id) + local size = creative_regions:get_areas_area_size(areas_area) + table.insert(current_regions_size, { ["id"]=id, ["size"]=size }) + if areas_area.owner == name then areas_owner = true - break - elseif a_area.open then + elseif areas_area.open then areas_open = true - break else areas_guest = true --continue @@ -73,36 +61,33 @@ function creative_regions:update_player(player) end end - local privstring = noregion_privs - if smallest_region.id then - if creative_regions.region_privs[tostring(smallest_region.id)] then - privstring = creative_regions.region_privs[tostring(smallest_region.id)] - else - privstring = default_privs + -- calculate privs starting with biggest region and overwriting conscutively + local new_privs_table = {} + creative_regions:add_privs_from_string(new_privs_table, noregion_privs) + + table.sort(current_regions_size, function(a,b) return a["size"] > b["size"] end) + + for _, region in ipairs(current_regions_size) do + player_active_region_str = player_active_region_str .. "," .. region.id + if creative_regions.region_privs[region.id] then + creative_regions:add_privs_from_string(new_privs_table, creative_regions.region_privs[region.id]) + elseif string.sub(region.id, 1, 1) == "r" then + creative_regions:add_privs_from_string(new_privs_table, default_privs) + elseif string.sub(region.id, 1, 1) == "a" then + creative_regions:add_privs_from_string(new_privs_table, areas_guest_privs) end end + + -- overwrite if areas_owner or areas_open then - privstring = privstring .. ", " .. areas_owner_privs - elseif areas_guest then - privstring = privstring .. ", " .. areas_guest_privs - for _, a in pairs(string.split(player_active_regions, ",")) do - a = a:trim() - if string.sub(a, 1, 1) == "a" then - if creative_regions.region_privs[a] then - privstring = privstring .. ", " .. creative_regions.region_privs[a] - end - end - end - if smallest_areas_area.size and smallest_region.size then - if smallest_region.size <= smallest_areas_area.size then - privstring = privstring .. ", " .. creative_regions.region_privs[tostring(smallest_region.id)] - end - end + creative_regions:add_privs_from_string(new_privs_table, areas_owner_privs) end - if player_active_regions ~= player_last_active_regions then - creative_regions:player_enter_region(player, privstring) - pmeta:set_string("creative_regions.active_regions", player_active_regions) + -- did the regions change? update + local player_last_active_region_str = pmeta:get_string("creative_regions.active_regions") or "" + if player_active_region_str ~= player_last_active_region_str then + creative_regions:player_enter_region(player, new_privs_table) + pmeta:set_string("creative_regions.active_regions", player_active_region_str) end -- print(dump(pmeta:to_table())) diff --git a/mod_areas.lua b/mod_areas.lua index 19d464e..4b8c2e3 100644 --- a/mod_areas.lua +++ b/mod_areas.lua @@ -20,7 +20,7 @@ if minetest.get_modpath("areas") then for astore_id, astore_area in pairs( current_regions ) do if astore_id then table.insert(areas, { - id = "mod:"..astore_id, + id = "region:"..astore_id, name = astore_area.data, --owner = "", }) diff --git a/player.lua b/player.lua index 2ab5b61..0a6dc87 100644 --- a/player.lua +++ b/player.lua @@ -54,11 +54,11 @@ function creative_regions:restore_player_inventory(player, listname) end end -function creative_regions:player_enter_region(player, privstring) +function creative_regions:player_enter_region(player, new_privs_table) local name = player:get_player_name() local has_creative = minetest.check_player_privs(name, {creative=true}) - local privs_grant, privs_revoke = creative_regions:decode_privs_string(privstring) + local privs_grant, privs_revoke = creative_regions:decode_privs_table(new_privs_table) if not has_creative and privs_grant.creative and not privs_revoke.creative then minetest.chat_send_player(name, "You entered creative mode") @@ -82,5 +82,4 @@ function creative_regions:player_enter_region(player, privstring) privs[newpriv] = nil end minetest.set_player_privs(name, privs) - end diff --git a/region.lua b/region.lua index dffd9ef..685cdbd 100644 --- a/region.lua +++ b/region.lua @@ -36,14 +36,12 @@ function creative_regions:set_region_privs(id, privs_string) creative_regions.region_privs[tostring(id)] = privs_string end -function creative_regions:decode_privs_string(str) - -- minetest/builtin/common/misc_helpers.lua:core.string_to_privs() - assert(type(str) == "string") - local delim = ',' +function creative_regions:decode_privs_table(privs_table) local privs_grant = {} local privs_revoke = {} - for _, priv in pairs(string.split(str, delim)) do - priv = priv:trim() + + table.sort(privs_table) + for _, priv in ipairs(privs_table) do local toggle = string.sub(priv, 1, 1) priv = string.sub(priv, 2) if toggle == '+' then @@ -54,9 +52,19 @@ function creative_regions:decode_privs_string(str) privs_grant[priv] = nil end end + return privs_grant, privs_revoke end -function creative_regions:add_privs_from_string(table, str) +function creative_regions:add_privs_from_string(privs_table, str) + -- minetest/builtin/common/misc_helpers.lua:core.string_to_privs() + assert(type(str) == "string") + local delim = ',' + local privs = {} + for _, priv in pairs(string.split(str, delim)) do + priv = priv:trim() + table.insert(privs_table, priv) + end + return privs end