commit cae887429243c1f26bc44c2b8e23cebab8c50beb Author: Hendrik Langer Date: Sat May 23 22:02:52 2020 +0200 first draft diff --git a/init.lua b/init.lua new file mode 100644 index 0000000..54d43dd --- /dev/null +++ b/init.lua @@ -0,0 +1,244 @@ +-- toggle_areas mod by h3ndrik + +toggle_areas = {} + +local mod_storage = minetest.get_mod_storage() +toggle_areas.astore = AreaStore() + +toggle_areas.area_privs = {} +toggle_areas.registered_on_enter = {} +toggle_areas.registered_on_leave = {} + +areas_owner_privs = minetest.settings:get("toggle_areas.owner_privs") ~= "+creative, +fly, +fast" +areas_guest_privs = minetest.settings:get("toggle_areas.guest_privs") ~= "-fly, -fast" +default_privs = minetest.settings:get("toggle_areas.default_privs") ~= "+fast" + +function toggle_areas:load_areas() + local test = minetest.deserialize(mod_storage:get_string("astore")) + local edge1 = { x=-10, y=-10, z=-10 } + local edge2 = { x=10, y=10, z=10 } + local data = "Testarea" + local astore_id = self.astore:insert_area(edge1, edge2, tostring(data)) + + self.set_area_privs(astore_id, "+fly, +fast, +creative") + + self.register_on_enter(astore_id, function(player) + local name = player:get_player_name() + local privs = minetest.get_player_privs(name) + minetest.log("warning", "[toggle_areas] callback worked") + privs.fly = true + privs.fast = false + minetest.set_player_privs(name, privs) + end) +end + +function toggle_areas:save_areas() + local datastr = minetest.serialize(self.astore) + if not datastr then + minetest.log("error", "[toggle_areas] Failed to serialize area data!") + return + end + mod_storage:set_string("astore", datastr) +end + +function toggle_areas:register_on_enter(id, func) + toggle_areas.registered_on_enter[id] = func +end + +function toggle_areas:set_area_privs(id, privs_string) + toggle_areas.area_privs[id] = privs_string +end + +function toggle_areas:decode_privs_string(str) + -- minetest/builtin/common/misc_helpers.lua:core.string_to_privs() + assert(type(str) == "string") + delim = ',' + local privs_grant = {} + local privs_revoke = {} + for _, priv in pairs(string.split(str, delim)) do + priv = priv:trim() + local toggle = string.sub(priv, 1, 1) + priv = string.sub(priv, 2) + if toggle == '+' then + privs_grant[priv] = true + elseif toggle == '-' then + privs_revoke[priv] = true + end + end + return privs_grant, privs_revoke +end + +function toggle_areas:is_areas_mod(area_id) + local is_areas_id = string.sub(id, 1, 2) == "a_" + local a_id = tonumber( string.sub(id, 3) ) + return is_areas_id, a_id +end + +function toggle_areas:get_area_size(area_id) + +end + +function toggle_areas:save_player_privs(player) + local name = player:get_player_name() + local pmeta = player:get_meta() + local privs = minetest.get_player_privs(name) + pmeta:set_string("toggle_areas_privs", minetest.serialize(privs)) +end + +function toggle_areas:restore_player_privs(player) + local name = player:get_player_name() + local pmeta = player:get_meta() + local privs = minetest.deserialize(pmeta:get_string("toggle_areas_privs")) + if privs then + minetest.set_player_privs(name, privs) + pmeta:set_string("toggle_areas_privs", nil) + end +end + +function toggle_areas:save_player_inventory(player, listname) + local name = player:get_player_name() + local pmeta = player:get_meta() + local inv = minetest.get_inventory({type="player", name=name}) + local player_items = inv:get_list("main") + inv:set_list(listname, player_items) +end + +function toggle_areas:restore_player_inventory(player, listname) + local name = player:get_player_name() + local pmeta = player:get_meta() + local inv = minetest.get_inventory({type="player", name=name}) + local player_items = inv:get_list(listname) or {} + inv:set_list("main", player_items) +end + +function toggle_areas:player_enter_area(player, privstring) + local name = player:get_player_name() + local has_creative = minetest.check_player_privs(name, {creative=true}) + + privs_grant, privs_revoke = toggle_areas:decode_privs_string(privstring) + + if not has_creative and privs_grant.creative and not privs_revoke.creative then + minetest.chat_send_player(name, "You entered creative mode") + toggle_areas:save_player_inventory(player, "saved_survival") + toggle_areas:restore_player_inventory(player, "saved_creative") + elseif has_creative and not privs_grant.creative then + minetest.chat_send_player(name, "You entered survival mode") + toggle_areas:save_player_inventory(player, "saved_creative") + toggle_areas:restore_player_inventory(player, "saved_survival") + end + + local has_privs = minetest.get_player_privs(name) + local privs = has_privs + for newpriv, _ in pairs(privs_grant) do + privs[newpriv] = true + end + for newpriv, _ in pairs(privs_revoke) do + privs[newpriv] = nil + end + minetest.set_player_privs(name, privs) + +end + +function toggle_areas:update_player(player) + local name = player:get_player_name() + local pos = vector.round(player:get_pos()) + + local pmeta = player:get_meta() +-- pmeta:mark_as_private("toggle_areas") + local player_stored_areas = minetest.deserialize(pmeta:get_string("toggle_areas")) or {} + local areas_owner = false + local areas_guest = false + + if minetest.check_player_privs(name, { protection_bypass=true }) then + minetest.log("warning", "[toggle_areas] Player has protection_bypass priv") + return + end + + -- enter areas mod area + local a_current_areas = {} + if minetest.get_modpath("areas") then + a_current_areas = areas:getAreasAtPos(pos) + for a_id, a_area in pairs( a_current_areas ) do + if a_area.owner == name then + areas_owner = true + else + areas_guest = true + end + if not player_stored_areas["a_"..a_id] then + player_stored_areas["a_"..a_id] = true + minetest.log("warning", "[toggle_areas] Player entered area a_"..tostring(a_id)) + + end + end + end + + -- enter area + local current_areas = self.astore:get_areas_for_pos(pos, false, true) + for astore_id, astore_area in pairs( current_areas ) do + if not player_stored_areas[astore_id] then + player_stored_areas[astore_id] = true + minetest.chat_send_player(name, "You entered area ["..tostring(astore_id).."] "..astore_area.data) + minetest.log("warning", "[toggle_areas] Player entered area "..tostring(astore_id)) +-- for i=1, #toggle_areas.registered_on_enter[astore_id] do +-- toggle_areas.registered_on_enter[astore_id][i](player) +-- end + end + end + + -- leave area + for id, _ in pairs(player_stored_areas) do + local is_areas_id, a_id = toggle_areas:is_areas_mod(id) + if not is_areas_id and not current_areas[id] then + player_stored_areas[id] = nil + minetest.log("warning", "[toggle_areas] Player left area "..tostring(id)) +-- for i=1, #toggle_areas.registered_on_leave[id] do +-- toggle_areas.registered_on_leave[id][i](player) +-- end + end + -- leave areas mod area + if is_areas_id and not a_current_areas[a_id] then + player_stored_areas[id] = nil + minetest.log("warning", "[toggle_areas] Player left areas area "..tostring(id)) + end + end + + local current_player_area = -1 + for id, _ in pairs(player_stored_areas) do + + end + local privstring = toggle_areas.area_privs[area_id] or default_privs + -- todo areas owner / guest + +-- print(dump(pmeta:to_table())) + pmeta:set_string("toggle_areas", minetest.serialize(player_stored_areas)) +end + +toggle_areas:load_areas() + +local timer = 0 +minetest.register_globalstep(function(dtime) + timer = timer + dtime + if timer >= 1 then + for _, player in pairs(minetest.get_connected_players()) do + toggle_areas:update_player(player) + end + end +end) + +-- areas mod hud +if minetest.get_modpath("areas") then + local function areas_hud_handler(pos, areas) + local current_areas = toggle_areas.astore:get_areas_for_pos(pos, false, true) + for astore_id, astore_area in pairs( current_areas ) do + if astore_id then + table.insert(areas, { + id = "mod:"..astore_id, + name = astore_area.data, + --owner = "", + }) + end + end + end + + areas:registerHudHandler(areas_hud_handler) +end diff --git a/mod.conf b/mod.conf new file mode 100644 index 0000000..d51d48b --- /dev/null +++ b/mod.conf @@ -0,0 +1,4 @@ +name = toggle_areas +description = Toggle privs in areas +depends = default, sfinv +optional_depends = areas, hunger_ng diff --git a/settingtypes.txt b/settingtypes.txt new file mode 100644 index 0000000..800a597 --- /dev/null +++ b/settingtypes.txt @@ -0,0 +1,8 @@ +# Privs of an areas mod owner +toggle_areas.owner_privs (Owner privs) string "+creative, +fly, +fast" + +# Privs of an areas mod guest +toggle_areas.guest_privs (Guest privs) string "-fly, -fast" + +# Default privs +toggle_areas.guest_privs (Default privs) string "+fast"