Add changeowner key #7654

Closed
opened 2024-11-15 07:52:03 +01:00 by AliasAlreadyTaken · 5 comments

Let's add an admintool "changeowner_key" which would on leftclick show a formspec, where the admin can insert the name and on rightclick set this name on chests and other "owned" blocks

Let's add an admintool "changeowner_key" which would on leftclick show a formspec, where the admin can insert the name and on rightclick set this name on chests and other "owned" blocks
AliasAlreadyTaken added the
1. kind/enhancement
label 2024-11-15 07:53:25 +01:00
AliasAlreadyTaken added this to the 1.1.126 milestone 2024-11-15 07:53:27 +01:00
Owner

including doors?

including doors?
Member

Not as easy as I thought... We assume this will not be used by untrusted users, right? (One might be able set bad strings with the formspec. Mods do not check for valid player names)

Also: the infotext of the nodes does not update... (I mean, we can do a string.gsub on it, but then we need to check against players called "owned" etc.) Do you want such a feature?

Code in comment tabs is a bit... weird? Is there a repo I can create a pr for?

local PRIV = "server"
local itemname = "test2:change_owner"
local texture = "settings_reset.png"

-- https://rubenwardy.com/minetest_modding_book/en/players/formspecs.html#contexts
local _contexts = {}
local function get_context(name)
    local context = _contexts[name] or {}
    _contexts[name] = context
    return context
end

minetest.register_on_leaveplayer(function(player)
    _contexts[player:get_player_name()] = nil
end)

-- ---------------------------------------------------------------------------------
local function change_owner(pos, new_owner)
    local meta = minetest.get_meta(pos)
    if not meta:contains("owner") then
        return "Node is not owned"
    end
    local old_owner = meta:get_string("owner")
    -- other mods expect their owners to be valid playernames, they do not formspec-escape it
    meta:set_string("owner", minetest.formspecs_escape(new_owner))
    -- logging???
    return string.format(
            "Changed owner at %s from %s to %s",
            minetest.pos_to_string(pos),
            old_owner,
            new_owner
    )
end

minetest.register_craftitem(itemname, {
    description = "change the owner of owned nodes",
    groups = {not_in_creative_inventory = 1},
    inventory_image = texture,
    stack_max = 1,
    on_use = function (itemstack, user, poined_thing)
        if not minetest.check_player_privs(user, PRIV) then
            -- itemstack:take_item()       -- player should not have this item, let's take it from him
            return itemstack
        end
        if poined_thing.type ~= "node" then
            return itemstack
        end

        local name = user:get_player_name()
        local pos = poined_thing.under
        local meta = minetest.get_meta(pos)
        if not meta:contains("owner") then
            minetest.chat_send_player(name, "Node is not owned")
            return itemstack
        end
        local old_owner = meta:get_string("owner")

        local ctx = get_context(name)
        ctx.pos = pos

        local fs = {
            "formspec_version[6]",
            "size[10,5]",
            "label[1.1,1.1;old owner]",
            "label[3.6,1.1;" .. old_owner .. "]",
            "label[1.1,2.4;new owner]",
            "field[3.6,2;5,0.8;new_owner;;]",
            "field_close_on_enter[new_owner;false]",
            "button_exit[3.6,3.4;3,0.8;rename;rename]"
        }
        minetest.show_formspec(name, "change_owner:change", table.concat(fs))

        return itemstack
    end,
    on_place = function (itemstack, user, poined_thing)
        if not minetest.check_player_privs(user, PRIV) then
            -- itemstack:take_item()       -- player should not have this item, let's take it from him
            return itemstack
        end
        if poined_thing.type ~= "node" then
            return itemstack
        end
        local name = user:get_player_name()
        local msg = change_owner(poined_thing.under, name)
        minetest.chat_send_player(name, msg)
        return itemstack
    end
})

minetest.register_on_player_receive_fields(function(player, formname, fields)
    if formname ~= "change_owner:change" then
        return false
    end
    if not minetest.check_player_privs(player, PRIV) then
        return true
    end
    local name = player:get_player_name()
    local pos = get_context(name).pos
    if fields.rename and fields.new_owner ~= "" and pos then
        local msg = change_owner(pos, fields.new_owner)
        minetest.chat_send_player(name, msg)
    end

    return true
end)

Not as easy as I thought... We assume this will not be used by untrusted users, right? (One might be able set bad strings with the formspec. Mods do not check for valid player names) Also: the infotext of the nodes does not update... (I mean, we can do a string.gsub on it, but then we need to check against players called "owned" etc.) Do you want such a feature? Code in comment tabs is a bit... weird? Is there a repo I can create a pr for? ```lua local PRIV = "server" local itemname = "test2:change_owner" local texture = "settings_reset.png" -- https://rubenwardy.com/minetest_modding_book/en/players/formspecs.html#contexts local _contexts = {} local function get_context(name) local context = _contexts[name] or {} _contexts[name] = context return context end minetest.register_on_leaveplayer(function(player) _contexts[player:get_player_name()] = nil end) -- --------------------------------------------------------------------------------- local function change_owner(pos, new_owner) local meta = minetest.get_meta(pos) if not meta:contains("owner") then return "Node is not owned" end local old_owner = meta:get_string("owner") -- other mods expect their owners to be valid playernames, they do not formspec-escape it meta:set_string("owner", minetest.formspecs_escape(new_owner)) -- logging??? return string.format( "Changed owner at %s from %s to %s", minetest.pos_to_string(pos), old_owner, new_owner ) end minetest.register_craftitem(itemname, { description = "change the owner of owned nodes", groups = {not_in_creative_inventory = 1}, inventory_image = texture, stack_max = 1, on_use = function (itemstack, user, poined_thing) if not minetest.check_player_privs(user, PRIV) then -- itemstack:take_item() -- player should not have this item, let's take it from him return itemstack end if poined_thing.type ~= "node" then return itemstack end local name = user:get_player_name() local pos = poined_thing.under local meta = minetest.get_meta(pos) if not meta:contains("owner") then minetest.chat_send_player(name, "Node is not owned") return itemstack end local old_owner = meta:get_string("owner") local ctx = get_context(name) ctx.pos = pos local fs = { "formspec_version[6]", "size[10,5]", "label[1.1,1.1;old owner]", "label[3.6,1.1;" .. old_owner .. "]", "label[1.1,2.4;new owner]", "field[3.6,2;5,0.8;new_owner;;]", "field_close_on_enter[new_owner;false]", "button_exit[3.6,3.4;3,0.8;rename;rename]" } minetest.show_formspec(name, "change_owner:change", table.concat(fs)) return itemstack end, on_place = function (itemstack, user, poined_thing) if not minetest.check_player_privs(user, PRIV) then -- itemstack:take_item() -- player should not have this item, let's take it from him return itemstack end if poined_thing.type ~= "node" then return itemstack end local name = user:get_player_name() local msg = change_owner(poined_thing.under, name) minetest.chat_send_player(name, msg) return itemstack end }) minetest.register_on_player_receive_fields(function(player, formname, fields) if formname ~= "change_owner:change" then return false end if not minetest.check_player_privs(player, PRIV) then return true end local name = player:get_player_name() local pos = get_context(name).pos if fields.rename and fields.new_owner ~= "" and pos then local msg = change_owner(pos, fields.new_owner) minetest.chat_send_player(name, msg) end return true end) ```
Author
Owner

This was my puny first attempt ....

minetest.register_tool("yl_commons:changeowner_key", {
    description = "Rightclick to set the new owner name, rightclick a chest to change the owner",
    inventory_image = "keys_key_skeleton.png^[multiply:#caffee",
    wield_image = "yl_commons_empty.png",
    range = 30.0,
    groups = {
        tool = 1,
        admintool = 1,
        not_in_creative_inventory = 1
    },
    on_secondary_use = function(itemstack, user, pointed_thing)
        return on_secondary_use(itemstack, user, pointed_thing)
    end,
    on_use = function(itemstack, user, pointed_thing)
        return on_use(itemstack, user, pointed_thing)
    end,
    on_drop = function(itemstack, dropper, pos)
        return
    end
})
This was my puny first attempt .... ```lua minetest.register_tool("yl_commons:changeowner_key", { description = "Rightclick to set the new owner name, rightclick a chest to change the owner", inventory_image = "keys_key_skeleton.png^[multiply:#caffee", wield_image = "yl_commons_empty.png", range = 30.0, groups = { tool = 1, admintool = 1, not_in_creative_inventory = 1 }, on_secondary_use = function(itemstack, user, pointed_thing) return on_secondary_use(itemstack, user, pointed_thing) end, on_use = function(itemstack, user, pointed_thing) return on_use(itemstack, user, pointed_thing) end, on_drop = function(itemstack, dropper, pos) return end }) ```
AliasAlreadyTaken added the
4. step/ready to QA test
label 2024-11-19 11:24:40 +01:00
Author
Owner

QA

  • anvil works, but doesn't change infotext
  • bones work
  • books can change author! infotext doesn't change
  • chesttools OK
  • cottages OK
  • digistuff:movestone works, but area owner can dig anyways
  • shared locked furnace works, but protection overlap
  • shared locked sign works, but protection overlap
  • markers work
  • command block and craftable command block work
  • smartshops work
  • tnt works
  • moremesecons_luablock:luablock works
  • npc signs do NOT work
  • pipeworks allows change owner, although I do not understand what difference it makes
  • shared works
  • basic signs, locked signs, signs_lib, signs_road work
QA * anvil works, but doesn't change infotext * bones work * books can change author! infotext doesn't change * chesttools OK * cottages OK * digistuff:movestone works, but area owner can dig anyways * shared locked furnace works, but protection overlap * shared locked sign works, but protection overlap * markers work * command block and craftable command block work * smartshops work * tnt works * moremesecons_luablock:luablock works * npc signs do NOT work * pipeworks allows change owner, although I do not understand what difference it makes * shared works * basic signs, locked signs, signs_lib, signs_road work
AliasAlreadyTaken added the
4. step/QA OK
label 2024-11-21 19:01:15 +01:00
Author
Owner

Was used a couple of times and works fine

Was used a couple of times and works fine
Sign in to join this conversation.
No Milestone
No project
No Assignees
3 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: your-land/bugtracker#7654
No description provided.