You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
244 lines
7.4 KiB
244 lines
7.4 KiB
-- 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
|
|
|