X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=builtin%2Fbuiltin.lua;h=d6782a49a03e22e460b42627b8e36acc85a415c0;hb=e297c739139ad0116ebdcda7a8dc5884d89f5a96;hp=45119be4855ad9ce5a8fb6b4424ecc49175898db;hpb=7cad0a2dcd817b179f82066964c45937a603d138;p=minetest.git diff --git a/builtin/builtin.lua b/builtin/builtin.lua index 45119be48..d6782a49a 100644 --- a/builtin/builtin.lua +++ b/builtin/builtin.lua @@ -100,7 +100,11 @@ function string:trim() return (self:gsub("^%s*(.-)%s*$", "%1")) end -assert(string.trim("\n \t\tfoo\t ") == "foo") +assert(string.trim("\n \t\tfoo bar\t ") == "foo bar") + +function minetest.pos_to_string(pos) + return "(" .. pos.x .. "," .. pos.y .. "," .. pos.z .. ")" +end -- -- Item definition helpers @@ -115,10 +119,6 @@ function minetest.inventorycube(img1, img2, img3) .. "{" .. img3:gsub("%^", "&") end -function minetest.pos_to_string(pos) - return "(" .. pos.x .. "," .. pos.y .. "," .. pos.z .. ")" -end - function minetest.get_pointed_thing_position(pointed_thing, above) if pointed_thing.type == "node" then if above then @@ -861,6 +861,14 @@ function minetest.get_connected_players() return list end +function minetest.hash_node_position(pos) + return (pos.z+32768)*65536*65536 + (pos.y+32768)*65536 + pos.x+32768 +end + +-- +-- Privileges +-- + minetest.registered_privileges = {} function minetest.register_privilege(name, description) minetest.registered_privileges[name] = description @@ -868,6 +876,7 @@ end minetest.register_privilege("interact", "Can interact with things and modify the world") minetest.register_privilege("teleport", "Can use /teleport command") +minetest.register_privilege("bring", "Can teleport other players") minetest.register_privilege("settime", "Can use /time") minetest.register_privilege("privs", "Can modify privileges") minetest.register_privilege("server", "Can do server maintenance stuff") @@ -892,8 +901,8 @@ end -- Register the help command minetest.register_chatcommand("help", { privs = {}, - params = "(nothing)/all/", - description = "Get help for commands", + params = "(nothing)/all/privs/", + description = "Get help for commands or list privileges", func = function(name, param) local format_help_line = function(cmd, def) local msg = "/"..cmd @@ -918,6 +927,11 @@ minetest.register_chatcommand("help", { minetest.chat_send_player(name, format_help_line(cmd, def)) end end + elseif param == "privs" then + minetest.chat_send_player(name, "Available privileges:") + for priv, desc in pairs(minetest.registered_privileges) do + minetest.chat_send_player(name, priv..": "..desc) + end else local cmd = param def = minetest.chatcommands[cmd] @@ -937,7 +951,6 @@ minetest.register_chatcommand("shutdown", {params = "", description = "shutdown minetest.register_chatcommand("setting", {params = " = ", description = "set line in configuration file", privs = {server=true}}) minetest.register_chatcommand("clearobjects", {params = "", description = "clear all objects in world", privs = {server=true}}) minetest.register_chatcommand("time", {params = "<0...24000>", description = "set time of day", privs = {settime=true}}) -minetest.register_chatcommand("teleport", {params = ",,", description = "teleport to given position", privs = {teleport=true}}) minetest.register_chatcommand("ban", {params = "", description = "ban IP of player", privs = {ban=true}}) minetest.register_chatcommand("unban", {params = "", description = "remove IP ban", privs = {ban=true}}) @@ -1006,6 +1019,7 @@ minetest.register_chatcommand("setpassword", { return end minetest.set_player_password(name, param) + minetest.chat_send_player(name, "Password set") end, }) minetest.register_chatcommand("clearpassword", { @@ -1014,6 +1028,99 @@ minetest.register_chatcommand("clearpassword", { privs = {password=true}, func = function(name, param) minetest.set_player_password(name, '') + minetest.chat_send_player(name, "Password cleared") + end, +}) + +minetest.register_chatcommand("teleport", { + params = ",, | | ,, | ", + description = "teleport to given position", + privs = {teleport=true}, + func = function(name, param) + -- Returns (pos, true) if found, otherwise (pos, false) + local function find_free_position_near(pos) + local tries = { + {x=1,y=0,z=0}, + {x=-1,y=0,z=0}, + {x=0,y=0,z=1}, + {x=0,y=0,z=-1}, + } + for _, d in ipairs(tries) do + local p = {x = pos.x+d.x, y = pos.y+d.y, z = pos.z+d.z} + local n = minetest.env:get_node(p) + if not minetest.registered_nodes[n.name].walkable then + return p, true + end + end + return pos, false + end + + local teleportee = nil + local p = {} + p.x, p.y, p.z = string.match(param, "^([%d.-]+)[, ] *([%d.-]+)[, ] *([%d.-]+)$") + teleportee = minetest.env:get_player_by_name(name) + if teleportee and p.x and p.y and p.z then + minetest.chat_send_player(name, "Teleporting to ("..p.x..", "..p.y..", "..p.z..")") + teleportee:setpos(p) + return + end + + local teleportee = nil + local p = nil + local target_name = nil + target_name = string.match(param, "^([^ ]+)$") + teleportee = minetest.env:get_player_by_name(name) + if target_name then + local target = minetest.env:get_player_by_name(target_name) + if target then + p = target:getpos() + end + end + if teleportee and p then + p = find_free_position_near(p) + minetest.chat_send_player(name, "Teleporting to "..target_name.." at ("..p.x..", "..p.y..", "..p.z..")") + teleportee:setpos(p) + return + end + + if minetest.check_player_privs(name, {bring=true}) then + local teleportee = nil + local p = {} + local teleportee_name = nil + teleportee_name, p.x, p.y, p.z = string.match(param, "^([^ ]+) +([%d.-]+)[, ] *([%d.-]+)[, ] *([%d.-]+)$") + if teleportee_name then + teleportee = minetest.env:get_player_by_name(teleportee_name) + end + if teleportee and p.x and p.y and p.z then + minetest.chat_send_player(name, "Teleporting "..teleportee_name.." to ("..p.x..", "..p.y..", "..p.z..")") + teleportee:setpos(p) + return + end + + local teleportee = nil + local p = nil + local teleportee_name = nil + local target_name = nil + teleportee_name, target_name = string.match(param, "^([^ ]+) +([^ ]+)$") + if teleportee_name then + teleportee = minetest.env:get_player_by_name(teleportee_name) + end + if target_name then + local target = minetest.env:get_player_by_name(target_name) + if target then + p = target:getpos() + end + end + if teleportee and p then + p = find_free_position_near(p) + minetest.chat_send_player(name, "Teleporting "..teleportee_name.." to "..target_name.." at ("..p.x..", "..p.y..", "..p.z..")") + teleportee:setpos(p) + return + end + end + + minetest.chat_send_player(name, "Invalid parameters (\""..param.."\") or player not found (see /help teleport)") + return end, }) @@ -1078,7 +1185,8 @@ local function read_auth_file() local newtable = {} local file, errmsg = io.open(minetest.auth_file_path, 'rb') if not file then - error(minetest.auth_file_path.." could not be opened for reading: "..errmsg) + minetest.log("info", minetest.auth_file_path.." could not be opened for reading ("..errmsg.."); assuming new world") + return end for line in file:lines() do if line ~= "" then @@ -1123,13 +1231,20 @@ minetest.builtin_auth_handler = { if not minetest.auth_table[name] then minetest.builtin_auth_handler.create_auth(name, minetest.get_password_hash(name, minetest.setting_get("default_password"))) end - if minetest.is_singleplayer() or name == minetest.setting_get("name") then + if minetest.is_singleplayer() then return { password = "", privileges = minetest.registered_privileges } else - return minetest.auth_table[name] + if minetest.auth_table[name] and name == minetest.setting_get("name") then + return { + password = minetest.auth_table[name].password, + privileges = minetest.registered_privileges + } + else + return minetest.auth_table[name] + end end end, create_auth = function(name, password)