diff --git a/chatcommands.lua b/chatcommands.lua new file mode 100644 index 0000000..6f0f67b --- /dev/null +++ b/chatcommands.lua @@ -0,0 +1,77 @@ +minetest.register_chatcommand("creative_region", { + params = " , , ", + description = "Set a creative region from a to b", + privs = {server = true}, + func = function(name, param) + local player = minetest.get_player_by_name(name) + if not player then + return false, "Player not found" + end + local found, _, x1, y1, z1, x2, y2, z2, region_name = param:find("^([+-]?%d+)%s+([+-]?%d+)%s+([+-]?%d+)%s*,%s*([+-]?%d+)%s+([+-]?%d+)%s+([+-]?%d+)%s*,%s*(.+)$") + if not found then + return false, "Syntax error" + end + + local edge1 = { x=tonumber(x1), y=tonumber(y1), z=tonumber(z1) } + local edge2 = { x=tonumber(x2), y=tonumber(y2), z=tonumber(z2) } + local data = region_name + local astore_id = creative_regions.astore:insert_area(edge1, edge2, tostring(data)) + if astore_id then + creative_regions:set_region_privs(tostring(astore_id), nil) + minetest.chat_send_player(name, "[creative_regions] New region set. ID: " .. astore_id) + creative_regions:save_regions() + return true, "Done" + else + return false, "Failed" + end + end, +}) + +minetest.register_chatcommand("creative_region_privs", { + params = ", ", + description = "Set privstring for creative region", + privs = {server = true}, + func = function(name, param) + local player = minetest.get_player_by_name(name) + if not player then + return false, "Player not found" + end + local found, _, region_id, privstring = param:find("^([+-]?%a?%d+)%s*,%s*(.+)$") + if not found then + return false, "Syntax error" + end + if privstring and region_id then + creative_regions:set_region_privs(tostring(region_id), privstring) + minetest.chat_send_player(name, "[creative_regions] Privstring set for region " .. region_id .. ": " .. privstring) + creative_regions:save_regions() + return true, "Done" + else + return false, "Failed" + end + end, +}) + +minetest.register_chatcommand("creative_region_rm", { + params = "", + description = "Remove a creative region", + privs = {server = true}, + func = function(name, param) + local player = minetest.get_player_by_name(name) + if not player then + return false, "Player not found" + end + local found, _, region_id = param:find("^([+-]?%d+)%s*$") + if not found then + return false, "Syntax error" + end + local success = creative_regions.astore:remove_area(tonumber(region_id)) + if success then + minetest.chat_send_player(name, "[creative_regions] Region " .. region_id .. "removed") + creative_regions:set_region_privs(tostring(region_id), nil) + else + minetest.chat_send_player(name, "[creative_regions] Error removing region " .. region_id) + end + creative_regions:save_regions() + return true, "Done." + end, +}) diff --git a/init.lua b/init.lua index e42dafa..f7b45b8 100644 --- a/init.lua +++ b/init.lua @@ -2,254 +2,19 @@ creative_regions = {} -local mod_storage = minetest.get_mod_storage() -creative_regions.astore = AreaStore() - -creative_regions.region_privs = {} areas_owner_privs = minetest.settings:get("creative_regions.owner_privs") or "+creative, +fast, +fly" areas_guest_privs = minetest.settings:get("creative_regions.guest_privs") or "-fly, -fast" noregion_privs = minetest.settings:get("creative_regions.noregion_privs") or "-creative, +fast, -fly" default_privs = minetest.settings:get("creative_regions.default_privs") or "+creative, +fast, +fly" -function creative_regions:load_regions() - self.astore:from_file(minetest.get_worldpath().."/creative_regions_regions") - creative_regions.region_privs = minetest.deserialize(mod_storage:get_string("astore_privs")) or {} --- local edge1 = { x=-10, y=-10, z=-10 } --- local edge2 = { x=10, y=10, z=10 } --- local data = "Testregion" --- local astore_id = self.astore:insert_area(edge1, edge2, tostring(data)) --- --- creative_regions:set_region_privs(astore_id, "+creative, +fast, +fly") -end - -function creative_regions:save_regions() - self.astore:to_file(minetest.get_worldpath().."/creative_regions_regions") - local datastr = minetest.serialize(creative_regions.region_privs) - if not datastr then - minetest.log("error", "[creative_regions] Failed to serialize region_privs data!") - return - end - mod_storage:set_string("astore_privs", datastr) -end - -function creative_regions:set_region_privs(id, privs_string) - creative_regions.region_privs[tostring(id)] = privs_string -end - -minetest.register_chatcommand("creative_region", { - params = " , , ", - description = "Set a creative region from a to b", - privs = {server = true}, - func = function(name, param) - local player = minetest.get_player_by_name(name) - if not player then - return false, "Player not found" - end - local found, _, x1, y1, z1, x2, y2, z2, region_name = param:find("^([+-]?%d+)%s+([+-]?%d+)%s+([+-]?%d+)%s*,%s*([+-]?%d+)%s+([+-]?%d+)%s+([+-]?%d+)%s*,%s*(.+)$") - if not found then - return false, "Syntax error" - end - - local edge1 = { x=tonumber(x1), y=tonumber(y1), z=tonumber(z1) } - local edge2 = { x=tonumber(x2), y=tonumber(y2), z=tonumber(z2) } - local data = region_name - local astore_id = creative_regions.astore:insert_area(edge1, edge2, tostring(data)) - if astore_id then - creative_regions:set_region_privs(tostring(astore_id), nil) - minetest.chat_send_player(name, "[creative_regions] New region set. ID: " .. astore_id) - creative_regions:save_regions() - return true, "Done" - else - return false, "Failed" - end - end, -}) - -minetest.register_chatcommand("creative_region_privs", { - params = ", ", - description = "Set privstring for creative region", - privs = {server = true}, - func = function(name, param) - local player = minetest.get_player_by_name(name) - if not player then - return false, "Player not found" - end - local found, _, region_id, privstring = param:find("^([+-]?%a?%d+)%s*,%s*(.+)$") - if not found then - return false, "Syntax error" - end - if privstring and region_id then - creative_regions:set_region_privs(tostring(region_id), privstring) - minetest.chat_send_player(name, "[creative_regions] Privstring set for region " .. region_id .. ": " .. privstring) - creative_regions:save_regions() - return true, "Done" - else - return false, "Failed" - end - end, -}) - -minetest.register_chatcommand("creative_region_rm", { - params = "", - description = "Remove a creative region", - privs = {server = true}, - func = function(name, param) - local player = minetest.get_player_by_name(name) - if not player then - return false, "Player not found" - end - local found, _, region_id = param:find("^([+-]?%d+)%s*$") - if not found then - return false, "Syntax error" - end - local success = creative_regions.astore:remove_area(tonumber(region_id)) - if success then - minetest.chat_send_player(name, "[creative_regions] Region " .. region_id .. "removed") - creative_regions:set_region_privs(tostring(region_id), nil) - else - minetest.chat_send_player(name, "[creative_regions] Error removing region " .. region_id) - end - creative_regions:save_regions() - return true, "Done." - end, -}) - -function creative_regions:decode_privs_string(str) - -- minetest/builtin/common/misc_helpers.lua:core.string_to_privs() - assert(type(str) == "string") - local 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 - privs_revoke[priv] = nil - elseif toggle == '-' then - privs_revoke[priv] = true - privs_grant[priv] = nil - end - end - return privs_grant, privs_revoke -end -function creative_regions:add_privs_from_string(table, str) +creative_regions.modpath = minetest.get_modpath("creative_regions") +dofile(creative_regions.modpath.."/region.lua") +dofile(creative_regions.modpath.."/player.lua") +dofile(creative_regions.modpath.."/chatcommands.lua") +dofile(creative_regions.modpath.."/mod_areas.lua") -end - -function creative_regions:is_areas_mod(area_id) - area_id = tostring(area_id) - local is_areas_id = string.sub(id, 1, 2) == "a" - local a_id = tonumber( string.sub(id, 2) ) - return is_areas_id, a_id -end - -function creative_regions:get_region_size(astore_area) - local pos1 = astore_area.min - local pos2 = astore_area.max - local x = math.abs( pos2.x - pos1.x ) - local z = math.abs( pos2.z - pos1.x ) - return x*z -end - -function creative_regions:get_areas_area_size(areas_area) - local pos1 = areas_area.pos1 - local pos2 = areas_area.pos2 - local x = math.abs( pos2.x - pos1.x ) - local z = math.abs( pos2.z - pos1.x ) - return x*z -end - -function creative_regions:initial_stuff() - local stuff_string = minetest.settings:get("initial_stuff") or - "default:pick_steel,default:axe_steel,default:shovel_steel," .. - "default:torch 99,default:cobble 99" - local itemtable = {} - local items = stuff_string:split(",") - for _, stack in ipairs(items) do - table.insert(itemtable, ItemStack(stack)) - end - return itemtable -end - -function creative_regions: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("creative_regions.saved_privs", minetest.serialize(privs)) -end - -function creative_regions:restore_player_privs(player) - local name = player:get_player_name() - local pmeta = player:get_meta() - local privs = minetest.deserialize(pmeta:get_string("creative_regions.saved_privs")) - if privs then - minetest.set_player_privs(name, privs) - pmeta:set_string("creative_regions.saved_privs", nil) - end -end - -function creative_regions:save_player_inventory(player, listname) - local name = player:get_player_name() - local pmeta = player:get_meta() - local inv = player:get_inventory() - local player_items = inv:get_list("main") - inv:set_list(listname, player_items) -end - -function creative_regions:restore_player_inventory(player, listname) - local name = player:get_player_name() - local pmeta = player:get_meta() - local inv = player:get_inventory() - local player_items = inv:get_list(listname) - local give_initial = false - if not player_items then - player_items = {} - give_initial = true - end - inv:set_list("main", player_items) - if give_initial then - local initial_items = creative_regions:initial_stuff() - for _, stack in ipairs(initial_items) do - inv:add_item("main", stack) - end - end - -end - -function creative_regions:player_enter_region(player, privstring) - 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) - - if not has_creative and privs_grant.creative and not privs_revoke.creative then - minetest.chat_send_player(name, "You entered creative mode") - creative_regions:save_player_inventory(player, "saved_survival") - creative_regions:restore_player_inventory(player, "saved_creative") - if minetest.get_modpath("unified_inventory") then - unified_inventory.set_inventory_formspec(player, unified_inventory.default) - end - elseif has_creative and privs_revoke.creative then - minetest.chat_send_player(name, "You entered survival mode") - creative_regions:save_player_inventory(player, "saved_creative") - creative_regions: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 creative_regions:update_player(player) local name = player:get_player_name() @@ -342,6 +107,7 @@ function creative_regions:update_player(player) -- print(dump(pmeta:to_table())) end + creative_regions:load_regions() local timer = 0 @@ -353,21 +119,3 @@ minetest.register_globalstep(function(dtime) end end end) - --- areas mod hud -if minetest.get_modpath("areas") then - local function areas_hud_handler(pos, areas) - local current_regions = creative_regions.astore:get_areas_for_pos(pos, false, true) - for astore_id, astore_area in pairs( current_regions ) 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_areas.lua b/mod_areas.lua new file mode 100644 index 0000000..19d464e --- /dev/null +++ b/mod_areas.lua @@ -0,0 +1,32 @@ +function creative_regions:is_areas_mod(area_id) + area_id = tostring(area_id) + local is_areas_id = string.sub(id, 1, 2) == "a" + local a_id = tonumber( string.sub(id, 2) ) + return is_areas_id, a_id +end + +function creative_regions:get_areas_area_size(areas_area) + local pos1 = areas_area.pos1 + local pos2 = areas_area.pos2 + local x = math.abs( pos2.x - pos1.x ) + local z = math.abs( pos2.z - pos1.x ) + return x*z +end + +-- areas mod hud +if minetest.get_modpath("areas") then + local function areas_hud_handler(pos, areas) + local current_regions = creative_regions.astore:get_areas_for_pos(pos, false, true) + for astore_id, astore_area in pairs( current_regions ) 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/player.lua b/player.lua new file mode 100644 index 0000000..2ab5b61 --- /dev/null +++ b/player.lua @@ -0,0 +1,86 @@ +function creative_regions:initial_stuff() + local stuff_string = minetest.settings:get("initial_stuff") or + "default:pick_steel,default:axe_steel,default:shovel_steel," .. + "default:torch 99,default:cobble 99" + local itemtable = {} + local items = stuff_string:split(",") + for _, stack in ipairs(items) do + table.insert(itemtable, ItemStack(stack)) + end + return itemtable +end + +function creative_regions: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("creative_regions.saved_privs", minetest.serialize(privs)) +end + +function creative_regions:restore_player_privs(player) + local name = player:get_player_name() + local pmeta = player:get_meta() + local privs = minetest.deserialize(pmeta:get_string("creative_regions.saved_privs")) + if privs then + minetest.set_player_privs(name, privs) + pmeta:set_string("creative_regions.saved_privs", nil) + end +end + +function creative_regions:save_player_inventory(player, listname) + local name = player:get_player_name() + local pmeta = player:get_meta() + local inv = player:get_inventory() + local player_items = inv:get_list("main") + inv:set_list(listname, player_items) +end + +function creative_regions:restore_player_inventory(player, listname) + local name = player:get_player_name() + local pmeta = player:get_meta() + local inv = player:get_inventory() + local player_items = inv:get_list(listname) + local give_initial = false + if not player_items then + player_items = {} + give_initial = true + end + inv:set_list("main", player_items) + if give_initial then + local initial_items = creative_regions:initial_stuff() + for _, stack in ipairs(initial_items) do + inv:add_item("main", stack) + end + end +end + +function creative_regions:player_enter_region(player, privstring) + 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) + + if not has_creative and privs_grant.creative and not privs_revoke.creative then + minetest.chat_send_player(name, "You entered creative mode") + creative_regions:save_player_inventory(player, "saved_survival") + creative_regions:restore_player_inventory(player, "saved_creative") + if minetest.get_modpath("unified_inventory") then + unified_inventory.set_inventory_formspec(player, unified_inventory.default) + end + elseif has_creative and privs_revoke.creative then + minetest.chat_send_player(name, "You entered survival mode") + creative_regions:save_player_inventory(player, "saved_creative") + creative_regions: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 diff --git a/region.lua b/region.lua new file mode 100644 index 0000000..dffd9ef --- /dev/null +++ b/region.lua @@ -0,0 +1,62 @@ +creative_regions.astore = AreaStore() +creative_regions.mod_storage = minetest.get_mod_storage() + +creative_regions.region_privs = {} + +function creative_regions:load_regions() + self.astore:from_file(minetest.get_worldpath().."/creative_regions_regions") + creative_regions.region_privs = minetest.deserialize(creative_regions.mod_storage:get_string("astore_privs")) or {} +-- local edge1 = { x=-10, y=-10, z=-10 } +-- local edge2 = { x=10, y=10, z=10 } +-- local data = "Testregion" +-- local astore_id = self.astore:insert_area(edge1, edge2, tostring(data)) +-- +-- creative_regions:set_region_privs(astore_id, "+creative, +fast, +fly") +end + +function creative_regions:save_regions() + self.astore:to_file(minetest.get_worldpath().."/creative_regions_regions") + local datastr = minetest.serialize(creative_regions.region_privs) + if not datastr then + minetest.log("error", "[creative_regions] Failed to serialize region_privs data!") + return + end + creative_regions.mod_storage:set_string("astore_privs", datastr) +end + +function creative_regions:get_region_size(astore_area) + local pos1 = astore_area.min + local pos2 = astore_area.max + local x = math.abs( pos2.x - pos1.x ) + local z = math.abs( pos2.z - pos1.x ) + return x*z +end + +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 = ',' + 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 + privs_revoke[priv] = nil + elseif toggle == '-' then + privs_revoke[priv] = true + privs_grant[priv] = nil + end + end + return privs_grant, privs_revoke +end + +function creative_regions:add_privs_from_string(table, str) + +end