2021-07-12 15:39:25 -07:00
|
|
|
|
|
|
|
--- Cleaner Chat Commands
|
|
|
|
--
|
|
|
|
-- @topic commands
|
|
|
|
|
|
|
|
|
2021-07-12 20:02:03 -07:00
|
|
|
local S = core.get_translator(cleaner.modname)
|
|
|
|
|
|
|
|
|
2021-07-12 15:39:25 -07:00
|
|
|
local function pos_list(ppos, radius)
|
|
|
|
local plist = {}
|
|
|
|
|
|
|
|
for x = ppos.x - radius, ppos.x + radius, 1 do
|
|
|
|
for y = ppos.y - radius, ppos.y + radius, 1 do
|
|
|
|
for z = ppos.z - radius, ppos.z + radius, 1 do
|
|
|
|
table.insert(plist, {x=x, y=y, z=z})
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
return plist
|
|
|
|
end
|
|
|
|
|
2021-07-12 21:43:16 -07:00
|
|
|
local param_desc = {
|
|
|
|
["radius"] = S("Search radius."),
|
|
|
|
["entity"] = S("Entity technical name."),
|
|
|
|
["node"] = S("Node technical name."),
|
|
|
|
["old_node"] = S("Technical name of node to be replaced."),
|
|
|
|
["new_node"] = S("Technical name of node to be used in place."),
|
|
|
|
["old_item"] = S("Technical name of item to be replaced."),
|
|
|
|
["new_item"] = S("Technical name of item to be used in place."),
|
|
|
|
["ore"] = S("Ore technical name."),
|
|
|
|
}
|
|
|
|
|
|
|
|
local function format_help(cmd, param_string, params)
|
|
|
|
local retval = S("Usage:") .. "\n /" .. cmd .. " " .. param_string
|
|
|
|
.. "\n"
|
|
|
|
|
|
|
|
local p_count = 0
|
|
|
|
for _, p in ipairs(params) do
|
|
|
|
if p_count == 0 then
|
|
|
|
retval = retval .. "\n" .. S("Params:")
|
|
|
|
end
|
|
|
|
|
|
|
|
retval = retval .. "\n " .. S(p) .. ": " .. param_desc[p]
|
|
|
|
p_count = p_count + 1
|
|
|
|
end
|
2021-07-12 15:39:25 -07:00
|
|
|
|
2021-07-12 21:43:16 -07:00
|
|
|
return retval
|
|
|
|
end
|
|
|
|
|
|
|
|
local cmd_repo = {
|
2021-07-12 20:02:03 -07:00
|
|
|
entity = {
|
2021-07-12 21:43:16 -07:00
|
|
|
cmd = "remove_entity",
|
|
|
|
params = "<" .. S("entity") .. "> [" .. S("radius") .. "]",
|
2021-07-12 20:02:03 -07:00
|
|
|
},
|
|
|
|
node = {
|
2021-07-12 21:43:16 -07:00
|
|
|
cmd_rem = "remove_node",
|
|
|
|
cmd_rep = "replace_node",
|
|
|
|
cmd_find = "find_unknown_nodes",
|
|
|
|
params_rem = "<" .. S("node") .. "> [" .. S("radius") .. "]",
|
|
|
|
params_rep = "<" .. S("old_node") .. "> <" .. S("new_node") .. "> [" .. S("radius") .. "]",
|
|
|
|
params_find = "[" .. S("radius") .. "]",
|
2021-07-12 20:02:03 -07:00
|
|
|
},
|
|
|
|
item = {
|
2021-07-12 21:43:16 -07:00
|
|
|
cmd = "replace_item",
|
|
|
|
params = "<" .. S("old_item") .. "> <" .. S("new_item") .. ">",
|
2021-07-12 20:02:03 -07:00
|
|
|
},
|
|
|
|
ore = {
|
2021-07-12 21:43:16 -07:00
|
|
|
cmd = "remove_ore",
|
|
|
|
params = "<" .. S("ore") .. ">",
|
2021-07-12 20:02:03 -07:00
|
|
|
},
|
|
|
|
param = {
|
|
|
|
missing = S("Missing parameter."),
|
|
|
|
excess = S("Too many parameters."),
|
|
|
|
mal_radius = S("Radius must be a number."),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-07-12 15:39:25 -07:00
|
|
|
--- Removes nearby entities.
|
|
|
|
--
|
|
|
|
-- @chatcmd remove_entity
|
|
|
|
-- @param entity Entity technical name.
|
2021-07-12 21:43:16 -07:00
|
|
|
-- @tparam[opt] int radius
|
|
|
|
core.register_chatcommand(cmd_repo.entity.cmd, {
|
2021-07-12 15:39:25 -07:00
|
|
|
privs = {server=true},
|
2021-07-12 20:02:03 -07:00
|
|
|
description = S("Remove an entity from game."),
|
2021-07-12 21:43:16 -07:00
|
|
|
params = cmd_repo.entity.params,
|
2021-07-12 15:39:25 -07:00
|
|
|
func = function(name, param)
|
|
|
|
local entity
|
|
|
|
local radius = 100
|
|
|
|
if param:find(" ") then
|
|
|
|
entity = param:split(" ")
|
|
|
|
radius = tonumber(entity[2])
|
|
|
|
entity = entity[1]
|
|
|
|
else
|
|
|
|
entity = param
|
|
|
|
end
|
|
|
|
|
2021-07-12 21:43:16 -07:00
|
|
|
local err
|
2021-07-12 15:39:25 -07:00
|
|
|
if not entity or entity:trim() == "" then
|
2021-07-12 21:43:16 -07:00
|
|
|
err = cmd_repo.param.missing
|
2021-07-12 15:39:25 -07:00
|
|
|
elseif not radius then
|
2021-07-12 21:43:16 -07:00
|
|
|
err = cmd_repo.param.mal_radius
|
|
|
|
end
|
|
|
|
|
|
|
|
if err then
|
|
|
|
return false, err .. "\n\n"
|
|
|
|
.. format_help(cmd_repo.entity.cmd, cmd_repo.entity.params, {"entity", "radius"})
|
2021-07-12 15:39:25 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
local player = core.get_player_by_name(name)
|
|
|
|
|
2021-07-12 21:43:16 -07:00
|
|
|
local total_removed = 0
|
2021-07-12 15:39:25 -07:00
|
|
|
for _, object in ipairs(core.get_objects_inside_radius(player:get_pos(), radius)) do
|
|
|
|
local lent = object:get_luaentity()
|
|
|
|
|
|
|
|
if lent then
|
|
|
|
if lent.name == entity then
|
|
|
|
object:remove()
|
2021-07-12 21:43:16 -07:00
|
|
|
total_removed = total_removed + 1
|
2021-07-12 15:39:25 -07:00
|
|
|
end
|
|
|
|
else
|
|
|
|
if object:get_properties().infotext == entity then
|
|
|
|
object:remove()
|
2021-07-12 21:43:16 -07:00
|
|
|
total_removed = total_removed + 1
|
2021-07-12 15:39:25 -07:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2021-07-12 21:43:16 -07:00
|
|
|
return true, S("Removed @1 entities.", total_removed)
|
2021-07-12 15:39:25 -07:00
|
|
|
end,
|
|
|
|
})
|
|
|
|
|
|
|
|
--- Removes nearby nodes.
|
|
|
|
--
|
|
|
|
-- @chatcmd remove_node
|
|
|
|
-- @param node Node technical name.
|
2021-07-12 21:43:16 -07:00
|
|
|
-- @tparam[opt] int radius
|
|
|
|
core.register_chatcommand(cmd_repo.node.cmd_rem, {
|
2021-07-12 15:39:25 -07:00
|
|
|
privs = {server=true},
|
2021-07-12 20:02:03 -07:00
|
|
|
description = S("Remove a node from game."),
|
2021-07-12 21:43:16 -07:00
|
|
|
params = cmd_repo.node.params_rem,
|
2021-07-12 15:39:25 -07:00
|
|
|
func = function(name, param)
|
|
|
|
local nname
|
|
|
|
local radius = 100
|
|
|
|
if param:find(" ") then
|
|
|
|
nname = param:split(" ")
|
|
|
|
radius = tonumber(nname[2])
|
|
|
|
nname = nname[1]
|
|
|
|
else
|
|
|
|
nname = param
|
|
|
|
end
|
|
|
|
|
2021-07-12 21:43:16 -07:00
|
|
|
local err
|
2021-07-12 15:39:25 -07:00
|
|
|
if not nname or nname:trim() == "" then
|
2021-07-12 21:43:16 -07:00
|
|
|
err = cmd_repo.param.missing
|
2021-07-12 15:39:25 -07:00
|
|
|
elseif not radius then
|
2021-07-12 21:43:16 -07:00
|
|
|
err = cmd_repo.param.mal_radius
|
|
|
|
end
|
|
|
|
|
|
|
|
if err then
|
|
|
|
return false, err .. "\n\n"
|
|
|
|
.. format_help(cmd_repo.node.cmd_rem, cmd_repo.node.params_rem, {"node", "radius"})
|
2021-07-12 15:39:25 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
local ppos = core.get_player_by_name(name):get_pos()
|
|
|
|
|
2021-07-12 21:43:16 -07:00
|
|
|
local total_removed = 0
|
2021-07-12 15:39:25 -07:00
|
|
|
for _, npos in ipairs(pos_list(ppos, radius)) do
|
|
|
|
local node = core.get_node_or_nil(npos)
|
|
|
|
if node and node.name == nname then
|
|
|
|
core.remove_node(npos)
|
2021-07-12 21:43:16 -07:00
|
|
|
total_removed = total_removed + 1
|
2021-07-12 15:39:25 -07:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2021-07-12 21:43:16 -07:00
|
|
|
return true, S("Removed @1 nodes.", total_removed)
|
2021-07-12 15:39:25 -07:00
|
|
|
end,
|
|
|
|
})
|
|
|
|
|
2021-07-12 22:37:43 -07:00
|
|
|
local function update_list(inv, listname, src, tgt)
|
2021-07-12 23:02:50 -07:00
|
|
|
if not inv then
|
|
|
|
cleaner.log("error", "cannot update list of unknown inventory")
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
2021-07-12 22:37:43 -07:00
|
|
|
local list = inv:get_list(listname)
|
|
|
|
if not list then
|
2021-07-12 23:02:50 -07:00
|
|
|
cleaner.log("warning", "unknown inventory list: " .. listname)
|
2021-07-12 22:37:43 -07:00
|
|
|
return
|
|
|
|
end
|
|
|
|
|
|
|
|
for idx, stack in pairs(list) do
|
|
|
|
if stack:get_name() == src then
|
|
|
|
local new_stack = ItemStack(tgt)
|
|
|
|
new_stack:set_count(stack:get_count())
|
|
|
|
inv:set_stack(listname, idx, new_stack)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2021-07-12 15:39:25 -07:00
|
|
|
local function replace_item(src, tgt)
|
|
|
|
if not core.registered_items[tgt] then
|
2021-07-12 20:02:03 -07:00
|
|
|
return false, S('Cannot use unknown item "@1" as replacement.', tgt)
|
2021-07-12 15:39:25 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
if core.registered_items[src] then
|
|
|
|
core.unregister_item(src)
|
|
|
|
end
|
|
|
|
|
|
|
|
core.register_alias(src, tgt)
|
2021-07-12 22:11:00 -07:00
|
|
|
|
2021-07-12 22:37:43 -07:00
|
|
|
local bags = core.get_modpath("bags") ~= nil
|
2021-07-12 23:03:23 -07:00
|
|
|
local armor = core.get_modpath("3d_armor") ~= nil
|
2021-07-12 22:37:43 -07:00
|
|
|
|
2021-07-12 22:11:00 -07:00
|
|
|
-- update player inventories
|
|
|
|
for _, player in ipairs(core.get_connected_players()) do
|
|
|
|
local pinv = player:get_inventory()
|
2021-07-12 22:37:43 -07:00
|
|
|
update_list(pinv, "main", src, tgt)
|
2021-07-12 22:11:00 -07:00
|
|
|
|
2021-07-12 22:37:43 -07:00
|
|
|
if bags then
|
|
|
|
for i = 1, 4 do
|
|
|
|
update_list(pinv, "bag" .. i .. "contents", src, tgt)
|
2021-07-12 22:11:00 -07:00
|
|
|
end
|
|
|
|
end
|
2021-07-12 23:03:23 -07:00
|
|
|
|
|
|
|
if armor then
|
|
|
|
local armor_inv = core.get_inventory({type="detached", name=player:get_player_name() .. "_armor"})
|
|
|
|
update_list(armor_inv, "armor", src, tgt)
|
|
|
|
end
|
2021-07-12 22:11:00 -07:00
|
|
|
end
|
|
|
|
|
2021-07-12 15:39:25 -07:00
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
|
|
|
--- Replaces an item.
|
|
|
|
--
|
|
|
|
-- @chatcmd replace_item
|
|
|
|
-- @param old_item Technical name of item to replace.
|
|
|
|
-- @param new_item Technical name of item to be used in place.
|
2021-07-12 21:43:16 -07:00
|
|
|
core.register_chatcommand(cmd_repo.item.cmd, {
|
2021-07-12 15:39:25 -07:00
|
|
|
privs = {server=true},
|
2021-07-12 20:02:03 -07:00
|
|
|
description = S("Replace an item in game."),
|
2021-07-12 21:43:16 -07:00
|
|
|
params = cmd_repo.item.params,
|
2021-07-12 15:39:25 -07:00
|
|
|
func = function(name, param)
|
2021-07-12 21:43:16 -07:00
|
|
|
local help = format_help(cmd_repo.item.cmd, cmd_repo.item.params, {"old_item", "new_item"})
|
|
|
|
|
2021-07-12 15:39:25 -07:00
|
|
|
if not param:find(" ") then
|
2021-07-12 21:43:16 -07:00
|
|
|
return false, cmd_repo.param.missing .. "\n\n" .. help
|
2021-07-12 15:39:25 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
local src = param:split(" ")
|
|
|
|
local tgt = src[2]
|
|
|
|
src = src[1]
|
|
|
|
|
|
|
|
local retval, msg = replace_item(src, tgt)
|
|
|
|
if not retval then
|
|
|
|
return false, msg
|
|
|
|
end
|
|
|
|
|
2021-07-12 21:43:16 -07:00
|
|
|
return true, S("Success!")
|
2021-07-12 15:39:25 -07:00
|
|
|
end,
|
|
|
|
})
|
|
|
|
|
|
|
|
--- Replaces nearby nodes.
|
|
|
|
--
|
2021-07-12 21:43:16 -07:00
|
|
|
-- FIXME: sometimes nodes on top disappear
|
|
|
|
--
|
|
|
|
-- @chatcmd replace_node
|
2021-07-12 15:39:25 -07:00
|
|
|
-- @param old_node Technical name of node to replace.
|
|
|
|
-- @param new_node Technical name of node to be used in place.
|
2021-07-12 21:43:16 -07:00
|
|
|
-- @tparam[opt] int radius
|
|
|
|
core.register_chatcommand(cmd_repo.node.cmd_rep, {
|
2021-07-12 15:39:25 -07:00
|
|
|
privs = {server=true},
|
2021-07-12 20:02:03 -07:00
|
|
|
description = S("Replace a node in game."),
|
2021-07-12 21:43:16 -07:00
|
|
|
params = cmd_repo.node.params_rep,
|
2021-07-12 15:39:25 -07:00
|
|
|
func = function(name, param)
|
2021-07-12 21:43:16 -07:00
|
|
|
local help = format_help(cmd_repo.node.cmd_rep, cmd_repo.node.params_rep, {"old_node", "new_node", "radius"})
|
|
|
|
|
2021-07-12 15:39:25 -07:00
|
|
|
if not param:find(" ") then
|
2021-07-12 21:43:16 -07:00
|
|
|
return false, cmd_repo.param.missing .. "\n\n" .. help
|
2021-07-12 15:39:25 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
local radius = 100
|
|
|
|
local params = param:split(" ")
|
|
|
|
|
|
|
|
local src = params[1]
|
|
|
|
local tgt = tostring(params[2])
|
|
|
|
if #params > 2 then
|
|
|
|
radius = tonumber(params[3])
|
|
|
|
end
|
|
|
|
|
|
|
|
if not radius then
|
2021-07-12 21:43:16 -07:00
|
|
|
return false, cmd_repo.param.mal_radius .. "\n\n" .. help
|
2021-07-12 15:39:25 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
local new_node = core.registered_nodes[tgt]
|
|
|
|
if not new_node then
|
2021-07-12 20:02:03 -07:00
|
|
|
return false, S('Cannot use unknown node "@1" as replacement.', tgt)
|
2021-07-12 15:39:25 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
local total_replaced = 0
|
|
|
|
local ppos = core.get_player_by_name(name):get_pos()
|
|
|
|
for _, npos in ipairs(pos_list(ppos, radius)) do
|
|
|
|
local node = core.get_node_or_nil(npos)
|
|
|
|
if node and node.name == src then
|
|
|
|
core.remove_node(npos)
|
|
|
|
core.place_node(npos, new_node)
|
|
|
|
total_replaced = total_replaced + 1
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2021-07-12 21:43:16 -07:00
|
|
|
return true, S("Replaced @1 nodes.", total_replaced)
|
2021-07-12 15:39:25 -07:00
|
|
|
end,
|
|
|
|
})
|
|
|
|
|
|
|
|
--- Checks for nearby unknown nodes.
|
|
|
|
--
|
|
|
|
-- @chatcmd find_unknown_nodes
|
|
|
|
-- @tparam[opt] int radius Search radius.
|
2021-07-12 21:43:16 -07:00
|
|
|
core.register_chatcommand(cmd_repo.node.cmd_find, {
|
2021-07-12 15:39:25 -07:00
|
|
|
privs = {server=true},
|
2021-07-12 20:02:03 -07:00
|
|
|
description = S("Find names of unknown nodes."),
|
2021-07-12 21:43:16 -07:00
|
|
|
params = cmd_repo.node.params_find,
|
2021-07-12 15:39:25 -07:00
|
|
|
func = function(name, param)
|
2021-07-12 21:43:16 -07:00
|
|
|
local help = format_help(cmd_repo.node.cmd_find, cmd_repo.node.params_find, {"radius"})
|
|
|
|
|
2021-07-12 15:39:25 -07:00
|
|
|
if param:find(" ") then
|
2021-07-12 21:43:16 -07:00
|
|
|
return false, cmd_repo.param.excess .. "\n\n" .. help
|
2021-07-12 15:39:25 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
local radius = 100
|
|
|
|
if param and param:trim() ~= "" then
|
|
|
|
radius = tonumber(param)
|
|
|
|
end
|
|
|
|
|
|
|
|
if not radius then
|
2021-07-12 21:43:16 -07:00
|
|
|
return false, cmd_repo.param.mal_radius .. "\n\n" .. help
|
2021-07-12 15:39:25 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
local ppos = core.get_player_by_name(name):get_pos()
|
|
|
|
|
|
|
|
local checked_nodes = {}
|
|
|
|
local unknown_nodes = {}
|
|
|
|
for _, npos in ipairs(pos_list(ppos, radius)) do
|
|
|
|
local node = core.get_node_or_nil(npos)
|
|
|
|
if node and not checked_nodes[node.name] then
|
|
|
|
if not core.registered_nodes[node.name] then
|
|
|
|
table.insert(unknown_nodes, node.name)
|
|
|
|
end
|
|
|
|
|
|
|
|
checked_nodes[node.name] = true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2021-07-12 21:43:16 -07:00
|
|
|
local msg
|
2021-07-12 15:39:25 -07:00
|
|
|
if #unknown_nodes > 0 then
|
2021-07-12 21:43:16 -07:00
|
|
|
msg = S("Found unknown nodes: @1", table.concat(unknown_nodes, ", "))
|
2021-07-12 15:39:25 -07:00
|
|
|
else
|
2021-07-12 21:43:16 -07:00
|
|
|
msg = S("No unknown nodes found.")
|
2021-07-12 15:39:25 -07:00
|
|
|
end
|
|
|
|
|
2021-07-12 21:43:16 -07:00
|
|
|
return true, msg
|
2021-07-12 15:39:25 -07:00
|
|
|
end,
|
|
|
|
})
|
2021-07-12 15:44:43 -07:00
|
|
|
|
|
|
|
|
|
|
|
--- Unsafe commands.
|
|
|
|
--
|
|
|
|
-- Enabled with `cleaner.unsafe` setting.
|
|
|
|
--
|
|
|
|
-- @section unsafe
|
|
|
|
|
|
|
|
|
|
|
|
if cleaner.unsafe then
|
|
|
|
--- Registers an ore to be removed.
|
|
|
|
--
|
|
|
|
-- @chatcmd remove_ore
|
|
|
|
-- @param ore Ore technical name.
|
2021-07-12 21:43:16 -07:00
|
|
|
core.register_chatcommand(cmd_repo.ore.cmd, {
|
2021-07-12 15:44:43 -07:00
|
|
|
privs = {server=true},
|
2021-07-12 20:02:03 -07:00
|
|
|
description = S("Remove an ore from game."),
|
2021-07-12 21:43:16 -07:00
|
|
|
params = cmd_repo.ore.params,
|
2021-07-12 15:44:43 -07:00
|
|
|
func = function(name, param)
|
2021-07-12 21:43:16 -07:00
|
|
|
local err
|
|
|
|
if not param or param:trim() == "" then
|
|
|
|
err = cmd_repo.param.missing
|
|
|
|
elseif param:find(" ") then
|
|
|
|
err = cmd_repo.param.excess
|
2021-07-12 15:44:43 -07:00
|
|
|
end
|
|
|
|
|
2021-07-12 21:43:16 -07:00
|
|
|
if err then
|
|
|
|
return false, err .. "\n\n" .. format_help(cmd_repo.ore.cmd, cmd_repo.ore.params, {"ore"})
|
|
|
|
end
|
2021-07-12 15:44:43 -07:00
|
|
|
|
2021-07-12 21:43:16 -07:00
|
|
|
local success = false
|
|
|
|
local msg
|
|
|
|
local registered, total_removed = cleaner.remove_ore(param)
|
|
|
|
|
|
|
|
if not registered then
|
|
|
|
msg = S('Ore "@1" not found, not unregistering.', param)
|
|
|
|
else
|
|
|
|
msg = S("Unregistered @1 ores (this will be undone after server restart).", total_removed)
|
|
|
|
success = true
|
|
|
|
end
|
2021-07-12 15:44:43 -07:00
|
|
|
|
2021-07-12 21:43:16 -07:00
|
|
|
return success, msg
|
2021-07-12 15:44:43 -07:00
|
|
|
end
|
|
|
|
})
|
|
|
|
end
|