-- 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