diff --git a/.cdb.json b/.cdb.json deleted file mode 100644 index ada3089..0000000 --- a/.cdb.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "type": "MOD", - "title": "Cleaner", - "short_description": "Remove/Replace unknown entities, nodes, & items.", - "license": "MIT", - "media_license": "CC0-1.0", - "tags": ["world_tools"], - "repo": "https://codeberg.org/AntumLuanti/mod-cleaner", - "issue_tracker": "https://codeberg.org/AntumLuanti/mod-cleaner/issues", - "forums": 18381 -} diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index 62c4b62..0000000 --- a/.gitattributes +++ /dev/null @@ -1,2 +0,0 @@ -.* export-ignore -*.py export-ignore diff --git a/.github/workflows/reference.yml b/.github/workflows/reference.yml deleted file mode 100644 index 29dec4c..0000000 --- a/.github/workflows/reference.yml +++ /dev/null @@ -1,30 +0,0 @@ - -name: Build Reference -on: - push: - tags: - - 'v[0-9]*' - workflow_dispatch: - -jobs: - build: - name: Build Reference - runs-on: ubuntu-latest - steps: - - name: Setup Lua - uses: leafo/gh-actions-lua@v8 - with: - luaVersion: 5.4 - - name: Setup Lua Rocks - uses: leafo/gh-actions-luarocks@v4 - - name: Setup dependencies - run: luarocks install --only-deps https://raw.githubusercontent.com/lunarmodules/LDoc/master/ldoc-scm-3.rockspec - - name: Setup LDoc - run: git clone --single-branch --branch=custom https://github.com/AntumDeluge/LDoc.git ldoc - - name: Checkout & Build Docs - run: git clone https://github.com/AntumMT/mod-cleaner.git cleaner && cd cleaner && chmod +x .ldoc/build_versioned_docs.sh && ./.ldoc/build_versioned_docs.sh - - name: Deploy - uses: peaceiris/actions-gh-pages@v3 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: cleaner/docs/ diff --git a/.ldoc/build_versioned_docs.sh b/.ldoc/build_versioned_docs.sh deleted file mode 100755 index 728103f..0000000 --- a/.ldoc/build_versioned_docs.sh +++ /dev/null @@ -1,98 +0,0 @@ -#!/usr/bin/env bash - -# place this file in mod ".ldoc" directory - - -d_config="$(dirname $(readlink -f $0))" - -cd "${d_config}/.." - -d_root="$(pwd)" -d_export="${d_export:-${d_root}/docs/reference}" - -cmd_ldoc="${d_root}/../ldoc/ldoc.lua" -if test -f "${cmd_ldoc}"; then - if test ! -x "${cmd_ldoc}"; then - chmod +x "${cmd_ldoc}" - fi -else - cmd_ldoc="ldoc" -fi - -# clean old files -rm -rf "${d_export}" - -# store current branch -main_branch="$(git branch --show-current)" - -html_out="\n\n\n\n\n\n\n" - -cd "${d_root}" -git checkout ${main_branch} - -echo -e "${html_out}" > "${d_export}/index.html" - -echo -e "\nDone!" diff --git a/.ldoc/config.ld b/.ldoc/config.ld deleted file mode 100644 index 10e46db..0000000 --- a/.ldoc/config.ld +++ /dev/null @@ -1,201 +0,0 @@ - -local dofile, print, error, type, table, ipairs, string, tostring -if import then - dofile = import("dofile") - print = import("print") - error = import("error") - type = import("type") - table = import("table") - ipairs = import("ipairs") - string = import("string") - tostring = import("tostring") -end - - -project = "Cleaner" -title = "Cleaner mod for Luanti" -format = "markdown" -not_luadoc=true -boilerplate = false -icon = "textures/cleaner_pencil.png" -favicon = "https://www.luanti.org/media/icon.svg" - -file = { - "settings.lua", - "api.lua", - "chat.lua", - "tools.lua", - ".ldoc/config.luadoc", -} - -new_type("chatcmd", "Chat Commands") -new_type("setting", "Settings") -new_type("tool", "Tools") -new_type("json", "JSON Configurations") - - -local function video_frame(src) - return '' -end - - -local tags -tags, custom_tags = dofile(".ldoc/tags.ld") - - --- START: handling items to prevent re-parsing - -local registered_items = {} - -local function is_registered(item) - if not registered_items[item.type] then return false end - - for _, tbl in ipairs(registered_items[item.type]) do - if item == tbl then - return true - end - end - - return false -end - -local function register(item) - if not registered_items[item.type] then - registered_items[item.type] = {} - end - - if not is_registered(item) then - table.insert(registered_items[item.type], item) - end -end - --- END: - - -local function format_setting_tag(desc, value) - return "\n- `" .. desc .. ":` `" .. value .. "`" -end - -local function setting_handler(item) - if not ipairs or not type then - return item - end - - local tags = { - {"settype", "type"}, - {"default"}, - {"min", "minimum value"}, - {"max", "maximum value"}, - } - - local def = { - ["settype"] = format_setting_tag("type", "string"), - } - - for _, t in ipairs(tags) do - local name = t[1] - local desc = t[2] - if not desc then desc = name end - - local value = item.tags[name] - if type(value) == "table" then - if #value > 1 then - local msg = item.file.filename .. " (line " .. item.lineno - .. "): multiple instances of tag \"" .. name .. "\" found" - if error then - error(msg) - elseif print then - print("WARNING: " .. msg) - end - end - - if value[1] then - def[name] = format_setting_tag(desc, value[1]) - end - end - end - - item.description = item.description .. "\n\n**Definition:**\n" .. def.settype - for _, t in ipairs({def.default, def.min, def.max}) do - if t then - item.description = item.description .. t - end - end - - return item -end - -local function chatcmd_handler(item) - for _, p in ipairs(item.params) do - if item.modifiers.param[p].opt then - item.name = item.name .. " [" .. p .. "]" - else - item.name = item.name .. " <" .. p .. ">" - end - end - - if #item.params > 0 then - local pstring = "### Parameters:\n" - for k, param in pairs(item.params) do - if type(k) == "number" then - local value = item.params.map[param] - - pstring = pstring .. '\n- ' - .. param .. '' - - local modifiers = item.modifiers.param[param] - if modifiers and modifiers.type then - pstring = pstring .. ' `' .. modifiers.type .. '`' - end - - if value then - pstring = pstring .. value - end - - if modifiers and modifiers.opt then - pstring = pstring .. " *(optional)*" - end - end - end - - item.description = item.description .. "\n\n" .. pstring - -- clear parameter list - item.params = {} - end - - return item -end - -function custom_display_name_handler(item, default_handler) - if not is_registered(item) then - if item.type == "setting" then - item = setting_handler(item) - elseif item.type == "chatcmd" then - item = chatcmd_handler(item) - end - - local parse_tags = {"priv", "note"} - for _, pt in ipairs(parse_tags) do - local tvalues = item.tags[pt] - if tvalues then - local tstring = "" - - local title = tags.get_title(pt) - if title then - tstring = tstring .. "\n\n### " .. title .. ":\n" - end - - for _, tv in ipairs(tvalues) do - tstring = tstring .. "\n- " .. tags.format(pt, tv) - end - - item.description = item.description .. tstring - end - end - end - - register(item) - return default_handler(item) -end diff --git a/.ldoc/config.luadoc b/.ldoc/config.luadoc deleted file mode 100644 index 7cb0044..0000000 --- a/.ldoc/config.luadoc +++ /dev/null @@ -1,55 +0,0 @@ - ---- World Path Configuration --- --- @topic config - - ---- Main configuration file. --- --- Registering items, entities, etc. for cleaning can be done in ***cleaner.json*** --- in the world directory (`/cleaner.json`). If it does not exist --- it will be created automatically when the server is started. --- --- It is formatted as follows: --- --- { --- "entities" : --- { --- "remove" : [] --- }, --- "items" : --- { --- "replace" : {} --- }, --- "nodes" : --- { --- "remove" : [], --- "replace" : {} --- }, --- "ores" : --- { --- "remove" : [] --- } --- } --- --- `remove` key works for nodes, entities, & ores. `replace` key works for --- nodes & items. Their functions are self-explanatory. --- --- @json cleaner.json --- @usage --- Cleaning nodes example: --- { --- "nodes" : --- { --- "remove" : --- [ --- "old:node_1", --- "old:node_2", --- ], --- "replace" : --- { --- "old:node_3" : "new:node_1", --- "old:node_4" : "new:node_2", --- }, --- }, --- } diff --git a/.ldoc/gendoc.sh b/.ldoc/gendoc.sh deleted file mode 100755 index 75ef2c3..0000000 --- a/.ldoc/gendoc.sh +++ /dev/null @@ -1,54 +0,0 @@ -#!/usr/bin/env bash - -# place this file in mod ".ldoc" directory - - -d_ldoc="$(dirname $(readlink -f $0))" -f_config="${d_ldoc}/config.ld" - -cd "${d_ldoc}/.." - -d_root="$(pwd)" -d_export="${d_export:-${d_root}/docs/reference}" - -cmd_ldoc="${d_ldoc}/ldoc/ldoc.lua" -if test ! -x "${cmd_ldoc}"; then - cmd_ldoc="ldoc" -fi - -# clean old files -rm -rf "${d_export}" - -vinfo="v$(grep "^version = " "${d_root}/mod.conf" | head -1 | sed -e 's/version = //')" -d_data="${d_export}/${vinfo}/data" - -# generate new doc files -"${cmd_ldoc}" --UNSAFE_NO_SANDBOX --multimodule -c "${f_config}" -d "${d_export}/${vinfo}" "${d_root}"; retval=$? - -# check exit status -if test ${retval} -ne 0; then - echo -e "\nan error occurred (ldoc return code: ${retval})" - exit ${retval} -fi - -# show version info -for html in $(find "${d_export}/${vinfo}" -type f -name "*.html"); do - sed -i -e "s|^

[cC]leaner

$|

Cleaner (${vinfo})

|" "${html}" -done - -# copy textures to data directory -echo -e "\ncopying textures ..." -mkdir -p "${d_data}" -texture_count=0 -for png in $(find "${d_root}/textures" -maxdepth 1 -type f -name "*.png"); do - t_png="${d_data}/$(basename ${png})" - if test -f "${t_png}"; then - echo "WARNING: not overwriting existing file: ${t_png}" - else - cp "${png}" "${d_data}" - texture_count=$((texture_count + 1)) - printf "\rcopied ${texture_count} textures" - fi -done - -echo -e "\n\nDone!" diff --git a/.ldoc/tags.ld b/.ldoc/tags.ld deleted file mode 100644 index 91ab6dd..0000000 --- a/.ldoc/tags.ld +++ /dev/null @@ -1,81 +0,0 @@ - -local tags = {} -local tag_list = {} -local custom_tags = {} - -local register_tag = function(name, tag) - local new_tag = {name, title=tag.title, hidden=tag.hidden, format=tag.format} - table.insert(custom_tags, new_tag) - tag_list[name] = {title=tag.title, format=tag.format} -end - -tags.get_title = function(tname) - local t = tag_list[tname] - if t then - return t.title - end -end - -tags.format = function(tname, value) - local t = tag_list[tname] - if t then - if type(t.format) == "function" then - value = t.format(value) - end - end - - return value -end - - -local new_tags = { - ["priv"] = { - title = "Required Privileges", - hidden = true, - }, - ["note"] = { - title = "Notes", - hidden = true, - format = function(value) - return "*" .. value .. "*" - end, - }, - ["video"] = { - title = "Video", - format = video_frame, - }, - ["youtube"] = { - title = "Video", - format = function(value) - return video_frame("https://www.youtube.com/embed/" .. value) - end, - }, - -- settings - ["settype"] = { - title = "Setting Type", - hidden = true, - }, - ["default"] = { - title = "Default Value", - hidden = true, - }, - -- craft items/tools - ["img"] = { - title = "Image", - format = function(value) - return "" - end, - }, - -- chat commands - ["chatparam"] = { - title = "Parameters", - hidden = true, - }, -} - -for k, v in pairs(new_tags) do - register_tag(k, v) -end - - -return tags, custom_tags diff --git a/LICENSE.txt b/LICENSE.txt index 357bcd0..9042c25 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,21 +1,13 @@ -The MIT License (MIT) - -Copyright © 2021 Jordan Irwin (AntumDeluge) - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + Version 2, December 2004 + + Copyright (C) 2004 Sam Hocevar + + Everyone is permitted to copy and distribute verbatim or modified + copies of this license document, and changing it is allowed as long + as the name is changed. + + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. You just DO WHAT THE FUCK YOU WANT TO. diff --git a/README.md b/README.md index 70253ef..77b9f63 100644 --- a/README.md +++ b/README.md @@ -1,86 +1,18 @@ -## Cleaner mod for Luanti - -### Description: - -A [Luanti (Minetest)][Luanti] mod that can be used to remove/replace unknown entities, nodes, & items. Originally forked from [PilzAdam's ***clean*** mod][f.pilzadam]. - -![screenshot](screenshot.png) - -### Licensing: - -- Code: [MIT](LICENSE.txt) -- Textures: CC0 - -### Requirements: - -- Luanti minimum version: 5.0 -- Depends: none - -### Usage: - -Registering items, entities, etc. for cleaning can be done in `cleaner.json` in the world directory. If it does not exist it will be created automatically when the server is started. - -It is formatted as follows: -```json -{ - "entities" : - { - "remove" : [] - }, - "items" : - { - "replace" : {} - }, - "nodes" : - { - "remove" : [], - "replace" : {} - }, - "ores" : - { - "remove" : [] - } -} -``` - -Cleaning nodes example: -```json -{ - "nodes" : - { - "remove" : [ - "old:node_1", - "old:node_2", - ], - "replace" : { - "old:node_3" : "new:node_1", - "old:node_4" : "new:node_2", - } - }, -} -``` - -`remove` key works for nodes, entities, & ores. `replace` key works for nodes & items. Their functions are self-explanatory. - -#### Settings: - -``` -cleaner.unsafe -- Enables unsafe methods & commands (remove_ore). -- type: bool -- default: false -``` - -### Links: - -- [![ContentDB](https://content.luanti.org/packages/AntumDeluge/cleaner/shields/title/)][ContentDB] -- [Forum](https://forum.luanti.org/viewtopic.php?t=18381) -- [Git repo](https://github.com/AntumMT/mod-cleaner) -- [Reference](https://antummt.github.io/mod-cleaner/reference/latest/) -- [Changelog](changelog.txt) -- [TODO](TODO.txt) +## Clean mod for [Minetest][] -[Luanti]: https://luanti.org/ -[f.pilzadam]: https://forum.luanti.org/viewtopic.php?t=2777 -[ContentDB]: https://content.luanti.org/packages/AntumDeluge/cleaner/ +--- +### **Description:** + +Fork of [PilzAdam's ***clean*** mod][f.pilzadam] for Minetest. + + +--- +### **Licensing:** + +[WTFPL](LICENSE.txt) + + +[Minetest]: http://www.minetest.net/ + +[f.pilzadam]: https://forum.minetest.net/viewtopic.php?t=2777 diff --git a/TODO.txt b/TODO.txt deleted file mode 100644 index b800544..0000000 --- a/TODO.txt +++ /dev/null @@ -1,14 +0,0 @@ - -TODO: -- update world file when chat commands are used -- update inventories when items are replaced: - - creative - - storage (chests, etc.) -- add LBM when removing an item if it is a node -- add "radius" option for pencil or "xlen", "ylen", & "zlen" options -- add "xrotate" & "zrorate" modes for pencil -- don't require "server" priv for "find_unknown_nodes" & "find_neaby_nodes" commands -- add chat command to find nodes with specified attributes -- may be better to update player inventories on login than add aliases for items -- use aliases for unknown nodes instead of LBM -- only use LBM when a node to replace is still registered diff --git a/api.lua b/api.lua deleted file mode 100644 index a894148..0000000 --- a/api.lua +++ /dev/null @@ -1,194 +0,0 @@ - ---- Cleaner API --- --- @topic api - - -local replace_items = {} -local replace_nodes = {} - - ---- Retrieves list of items to be replaced. --- --- @treturn table Items to be replaced. -function cleaner.get_replace_items() - return replace_items -end - ---- Retrieves list of nodes to be replaced. --- --- @treturn table Nodes to be replaced. -function cleaner.get_replace_nodes() - return replace_nodes -end - - ---- Registers an entity to be removed. --- --- @tparam string src Entity technical name. -function cleaner.register_entity_removal(src) - core.register_entity(":" .. src, { - on_activate = function(self, ...) - self.object:remove() - end, - }) -end - ---- Registers a node to be removed. --- --- @tparam string src Node technical name. -function cleaner.register_node_removal(src) - core.register_node(":" .. src, { - groups = {to_remove=1}, - }) -end - -local function update_list(inv, listname, src, tgt) - if not inv then - cleaner.log("error", "cannot update list of unknown inventory") - return - end - - local list = inv:get_list(listname) - if not list then - cleaner.log("warning", "unknown inventory list: " .. listname) - 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 - ---- Replaces an item with another registered item. --- --- @tparam string src Technical name of item to be replaced. --- @tparam string tgt Technical name of item to be used in place. --- @tparam[opt] bool update_players `true` updates inventory lists associated with players (default: `false`). -function cleaner.replace_item(src, tgt, update_players) - update_players = not (update_players ~= true) - - if not core.registered_items[tgt] then - return false, S('Cannot use unknown item "@1" as replacement.', tgt) - end - - if not core.registered_items[src] then - cleaner.log("info", "\"" .. src .. "\" not registered, not unregistering") - else - cleaner.log("warning", "overriding registered item \"" .. src .. "\"") - - core.unregister_item(src) - if core.registered_items[src] then - cleaner.log("error", "could not unregister \"" .. src .. "\"") - end - end - - core.register_alias(src, tgt) - if core.registered_aliases[src] == tgt then - cleaner.log("info", "registered alias \"" .. src .. "\" for \"" .. tgt .. "\"") - else - cleaner.log("error", "could not register alias \"" .. src .. "\" for \"" .. tgt .. "\"") - end - - local bags = core.get_modpath("bags") ~= nil - local armor = core.get_modpath("3d_armor") ~= nil - - -- update player inventories - if update_players then - for _, player in ipairs(core.get_connected_players()) do - local pinv = player:get_inventory() - update_list(pinv, "main", src, tgt) - - if bags then - for i = 1, 4 do - update_list(pinv, "bag" .. i .. "contents", src, tgt) - end - end - - 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 - end - end - - return true -end - ---- Registeres an item to be replaced. --- --- @tparam string src Technical name of item to be replaced. --- @tparam string tgt Technical name of item to be used in place. -function cleaner.register_item_replacement(src, tgt) - replace_items[src] = tgt -end - ---- Registers a node to be replaced. --- --- @tparam string src Technical name of node to be replaced. --- @tparam string tgt Technical name of node to be used in place. -function cleaner.register_node_replacement(src, tgt) - core.register_node(":" .. src, { - groups = {to_replace=1}, - }) - - replace_nodes[src] = tgt - cleaner.register_item_replacement(src, tgt) -end - - ---- Unsafe Methods. --- --- Enabled with [cleaner.unsafe](settings.html#cleaner.unsafe) setting. --- --- @section unsafe - - -if cleaner.unsafe then - local remove_ores = {} - - --- Retrieves list of ores to be removed. - -- - -- @treturn table Ores to be removed. - function cleaner.get_remove_ores() - return remove_ores - end - - --- Registers an ore to be removed after server startup. - -- - -- @tparam string src Ore technical name. - function cleaner.register_ore_removal(src) - table.insert(remove_ores, src) - end - - --- Removes an ore definition. - -- - -- @tparam string src Ore technical name. - function cleaner.remove_ore(src) - local remove_ids = {} - local total_removed = 0 - local registered = false - - for id, def in pairs(core.registered_ores) do - if def.ore == src then - table.insert(remove_ids, id) - registered = true - end - end - - for _, id in ipairs(remove_ids) do - core.registered_ores[id] = nil - if core.registered_ores[id] then - cleaner.log("error", "unable to unregister ore " .. id) - else - total_removed = total_removed + 1 - end - end - - return registered, total_removed - end -end diff --git a/changelog.txt b/changelog.txt deleted file mode 100644 index 0214081..0000000 --- a/changelog.txt +++ /dev/null @@ -1,63 +0,0 @@ - -2025-01-18 ----------- -- fix undeclared global -- added nil check after reading world data file - - -v1.2.1 ----- -- use sounds mod for sounds -- added nil check after reading world data file - - -v1.2 ----- -- added API -- added support for unregistering ores (unsafe) -- added setting for enabling "unsafe" methods & commands -- all types are loaded from /cleaner.json file -- added localization support -- added Spanish localization -- added pencil tool for erasing, adding, & swapping nodes -- added chat commands: - - remove_entities - - remove_nodes - - replace_items - - replace_nodes - - find_unknown_nodes - - find_nearby_nodes - - remove_ores (unsafe) - - ctool (manages wielded cleaner tool settings) - -v1.1 ----- -- uses "register_lbm" with "run_at_every_load" instead of "register_abm" to save resources - - suggested by bell07 ( https://forum.luanti.org/viewtopic.php?p=325519#p325519 ) - -v1.0 ----- -- changed license to MIT -- "clean_entities" & "clean_nodes" files now use json format -- nodes can be replaced with other nodes -- items can be replaced with other items (/clean_items.json file) - -v0.4 ----- -- changed technical name to "cleaner" -- re-added functionality to clean nodes - -v0.3 ----- -- removed functionality for cleaning anything other than entities - -v0.2 ----- -- changed license to CC0 -- added some log output -- entities to be cleaned can be configured & loaded from world directory - -v0.1 ----- -- forked from PilzAdam's "clean" mod @ forum post updated: 2013-06-08 -- replaced deprecated call to "minetest.env" diff --git a/chat.lua b/chat.lua deleted file mode 100644 index 3f7cf43..0000000 --- a/chat.lua +++ /dev/null @@ -1,660 +0,0 @@ - ---- Cleaner Chat Commands --- --- @topic commands - - -local S = core.get_translator(cleaner.modname) - - -local aux = dofile(cleaner.modpath .. "/misc_functions.lua") - -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 - -local param_def = { - radius = {name=S("radius"), desc=S("Search radius.")}, - entity = {name=S("entity"), desc=S("Entity technical name.")}, - node = {name=S("node"), desc=S("Node technical name.")}, - old_node = {name=S("old_node"), desc=S("Technical name of node to be replaced.")}, - new_node = {name=S("new_node"), desc=S("Technical name of node to be used in place.")}, - old_item = {name=S("old_item"), desc=S("Technical name of item to be replaced.")}, - new_item = {name=S("new_item"), desc=S("Technical name of item to be used in place.")}, - ore = {name=S("ore"), desc=S("Ore technical name.")}, - action = {name=S("action"), - desc=S('Action to execute. Can be one of "@1", "@2", or "@3".', "status", "setmode", "setnode")}, - value = {name=S("value"), desc=S('Mode or node to be set for tool (not required for "@1" action).', "status")}, -} - -local cmd_repo = { - entity = { - cmd = "remove_entities", - params = {"entity"}, - oparams = {radius=100}, - }, - rem_node = { - cmd = "remove_nodes", - params = {"node"}, - oparams = {radius=5}, - }, - rep_node = { - cmd = "replace_nodes", - params = {"old_node", "new_node"}, - oparams = {radius=5}, - }, - find_node = { - cmd = "find_unknown_nodes", - oparams = {radius=100}, - }, - near_node = { - cmd = "find_nearby_nodes", - oparams = {radius=5}, - }, - item = { - cmd = "replace_items", - params = {"old_item", "new_item"}, - }, - ore = { - cmd = "remove_ores", - params = {"ore"}, - }, - tool = { - cmd = "ctool", - params = {"action", "value"}, - }, - param = { - missing = S("Missing parameter."), - excess = S("Too many parameters."), - mal_radius = S("Radius must be a number."), - }, -} - -for k, def in pairs(cmd_repo) do - if k ~= "param" then - local cmd_help = { - param_string = "", - usage_string = "/" .. def.cmd, - } - - if def.params or def.oparams then - if def.params then - local params = {} - for _, p in ipairs(def.params) do - -- translate - table.insert(params, S(p)) - end - - cmd_help.param_string = "<" .. table.concat(params, "> <") .. ">" - end - end - - if def.oparams then - for k, v in pairs(def.oparams) do - local op = k - if type(op) == "number" then - op = v - end - - cmd_help.param_string = cmd_help.param_string .. " [" .. S(op) .. "]" - end - end - - if cmd_help.param_string ~= "" then - cmd_help.usage_string = cmd_help.usage_string .. " " .. cmd_help.param_string - end - - cmd_repo[k].help = cmd_help - end -end - -local function get_cmd_def(cmd) - for k, v in pairs(cmd_repo) do - if v.cmd == cmd then return v end - end -end - -local function format_usage(cmd) - local def = get_cmd_def(cmd) - if def then - return S("Usage:") .. "\n " .. def.help.usage_string - end -end - -local function format_params(cmd) - local def = get_cmd_def(cmd) - - local param_count - -- FIXME: unused? - local all_params = {} - if def.params then - for _, p in ipairs(def.params) do - table.insert(all_params, p) - end - end - if def.oparams then - for k, v in pairs(def.oparams) do - - end - end - - local retval = "" - local p_count = 0 - - if def.params then - for _, p in ipairs(def.params) do - if p_count == 0 then - retval = retval .. S("Params:") - end - - retval = retval .. "\n " .. S(p) .. ": " .. param_def[p].desc - - p_count = p_count + 1 - end - end - - if def.oparams then - for k, v in pairs(def.oparams) do - if p_count == 0 then - retval = retval .. S("Params:") - end - - local p = k - local dvalue = v - if type(p) == "number" then - p = v - dvalue = nil - end - - retval = retval .. "\n " .. S(p) .. ": " .. param_def[p].desc - if dvalue then - retval = retval .. " (" .. S("default: @1", dvalue) .. ")" - end - - p_count = p_count + 1 - end - end - - return retval -end - -local function format_help(cmd) - return format_usage(cmd) .. "\n\n" .. format_params(cmd) -end - - -local function check_radius(radius, pname) - local is_admin = core.check_player_privs(pname, {server=true}) - - if not is_admin and radius > 10 then - radius = 10 - return radius, S("You do not have permission to set radius that high. Reduced to @1.", radius) - end - - if radius > 100 then - radius = 100 - return radius, S("Radius is too high. Reduced to @1.", radius) - end - - return radius -end - - ---- Removes nearby entities. --- --- @chatcmd remove_entities --- @param entity Entity technical name. --- @tparam[opt] int radius Search radius (default: 100). --- @priv server --- @usage --- # remove all mobs:horse entities within a radius of 10 nodes --- /remove_entities mobs:horse 10 -core.register_chatcommand(cmd_repo.entity.cmd, { - privs = {server=true}, - description = S("Remove an entity from game.") .. "\n\n" - .. format_params(cmd_repo.entity.cmd), - params = cmd_repo.entity.help.param_string, - func = function(name, param) - local entity - local radius = cmd_repo.entity.oparams.radius - if param:find(" ") then - entity = param:split(" ") - radius = tonumber(entity[2]) - entity = entity[1] - else - entity = param - end - - local err - if not entity or entity:trim() == "" then - err = cmd_repo.param.missing - elseif not radius then - err = cmd_repo.param.mal_radius - end - - local radius, msg = check_radius(radius, name) - if msg then - core.chat_send_player(name, msg) - end - - if err then - return false, err .. "\n\n" .. format_help(cmd_repo.entity.cmd) - end - - local player = core.get_player_by_name(name) - - local total_removed = 0 - 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() - total_removed = total_removed + 1 - end - else - if object:get_properties().infotext == entity then - object:remove() - total_removed = total_removed + 1 - end - end - end - - return true, S("Removed @1 entities.", total_removed) - end, -}) - ---- Removes nearby nodes. --- --- @chatcmd remove_nodes --- @param node Node technical name. --- @tparam[opt] int radius Search radius (default: 5). --- @priv server --- @usage --- # remove all default:dirt nodes within a radius of 10 --- /remove_nodes default:dirt 10 -core.register_chatcommand(cmd_repo.rem_node.cmd, { - privs = {server=true}, - description = S("Remove a node from game.") .. "\n\n" - .. format_params(cmd_repo.rem_node.cmd), - params = cmd_repo.rem_node.help.param_string, - func = function(name, param) - local nname - local radius = cmd_repo.rem_node.oparams.radius - if param:find(" ") then - nname = param:split(" ") - radius = tonumber(nname[2]) - nname = nname[1] - else - nname = param - end - - local err - if not nname or nname:trim() == "" then - err = cmd_repo.param.missing - elseif not radius then - err = cmd_repo.param.mal_radius - end - - local radius, msg = check_radius(radius, name) - if msg then - core.chat_send_player(name, msg) - end - - if err then - return false, err .. "\n\n" .. format_help(cmd_repo.rem_node.cmd) - end - - local ppos = core.get_player_by_name(name):get_pos() - - local total_removed = 0 - 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) - total_removed = total_removed + 1 - end - end - - return true, S("Removed @1 nodes.", total_removed) - end, -}) - ---- Replaces an item. --- --- @chatcmd replace_items --- @param old_item Technical name of item to replace. --- @param new_item Technical name of item to be used in place. --- @priv server --- @usage --- # replace default:sword_wood with default:sword_mese --- /replace_items default:sword_wood default:sword_mese -core.register_chatcommand(cmd_repo.item.cmd, { - privs = {server=true}, - description = S("Replace an item in game.") .. "\n\n" - .. format_params(cmd_repo.item.cmd), - params = cmd_repo.item.help.param_string, - func = function(name, param) - if not param:find(" ") then - return false, cmd_repo.param.missing .. "\n\n" .. format_help(cmd_repo.item.cmd) - end - - local src = param:split(" ") - local tgt = src[2] - src = src[1] - - local retval, msg = cleaner.replace_item(src, tgt, true) - if not retval then - return false, msg - end - - return true, S("Success!") - end, -}) - ---- Replaces nearby nodes. --- --- @chatcmd replace_nodes --- @param old_node Technical name of node to replace. --- @param new_node Technical name of node to be used in place. --- @tparam[opt] int radius Search radius (default: 5). --- @priv server --- @usage --- # replace all default:dirt nodes with default:cobble within a radius of 10 --- /replace_nodes default:dirt default:cobble 10 -core.register_chatcommand(cmd_repo.rep_node.cmd, { - privs = {server=true}, - description = S("Replace a node in game.") .. "\n\n" - .. format_params(cmd_repo.rep_node.cmd), - params = cmd_repo.rep_node.help.param_string, - func = function(name, param) - local help = format_help(cmd_repo.rep_node.cmd) - - if not param:find(" ") then - return false, cmd_repo.param.missing .. "\n\n" .. help - end - - local radius = cmd_repo.rep_node.oparams.radius - 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 - return false, cmd_repo.param.mal_radius .. "\n\n" .. help - end - - local radius, msg = check_radius(radius, name) - if msg then - core.chat_send_player(name, msg) - end - - if not core.registered_nodes[tgt] then - return false, S('Cannot use unknown node "@1" as replacement.', tgt) - 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 - if core.swap_node(npos, {name=tgt}) then - total_replaced = total_replaced + 1 - else - cleaner.log("error", "could not replace node at " .. core.pos_to_string(npos, 0)) - end - end - end - - return true, S("Replaced @1 nodes.", total_replaced) - end, -}) - ---- Checks for nearby unknown nodes. --- --- @chatcmd find_unknown_nodes --- @tparam[opt] int radius Search radius (default: 100). --- @priv server --- @usage --- # print names of all unknown nodes within radius of 10 --- /find_unknown_nodes 10 -core.register_chatcommand(cmd_repo.find_node.cmd, { - privs = {server=true}, - description = S("Find names of unknown nodes.") .. "\n\n" - .. format_params(cmd_repo.find_node.cmd), - params = cmd_repo.find_node.help.param_string, - func = function(name, param) - local help = format_help(cmd_repo.find_node.cmd) - - if param:find(" ") then - return false, cmd_repo.param.excess .. "\n\n" .. help - end - - local radius = cmd_repo.find_node.oparams.radius - if param and param:trim() ~= "" then - radius = tonumber(param) - end - - if not radius then - return false, cmd_repo.param.mal_radius .. "\n\n" .. help - end - - local radius, msg = check_radius(radius, name) - if msg then - core.chat_send_player(name, msg) - 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 - - local node_count = #unknown_nodes - if node_count > 0 then - msg = S("Found unknown nodes: @1", node_count) .. "\n " .. table.concat(unknown_nodes, ", ") - else - msg = S("No unknown nodes found.") - end - - return true, msg - end, -}) - ---- Finds names of nearby nodes. --- --- @chatcmd find_nearby_nodes --- @tparam[opt] int radius Search radius (default: 5). --- @priv server --- @usage --- # print names of all node types found within radius of 10 --- /find_nearby_nodes 10 -core.register_chatcommand(cmd_repo.near_node.cmd, { - privs = {server=true}, - description = S("Find names of nearby nodes.") .. "\n\n" - .. format_params(cmd_repo.near_node.cmd), - params = cmd_repo.near_node.help.param_string, - func = function(name, param) - local help = format_help(cmd_repo.near_node.cmd) - - if param:find(" ") then - return false, cmd_repo.param.excess .. "\n\n" .. help - end - - local radius = cmd_repo.near_node.oparams.radius - if param and param:trim() ~= "" then - radius = tonumber(param) - end - - if not radius then - return false, cmd_repo.param.mal_radius .. "\n\n" .. help - end - - local radius, msg = check_radius(radius, name) - if msg then - core.chat_send_player(name, msg) - end - - local ppos = core.get_player_by_name(name):get_pos() - - local node_names = {} - for _, npos in ipairs(pos_list(ppos, radius)) do - local node = core.get_node_or_nil(npos) - if node and not node_names[node.name] then - node_names[node.name] = true - end - end - - local found_nodes = {} - for k, _ in pairs(node_names) do - table.insert(found_nodes, k) - end - - local msg - local node_count = #found_nodes - if node_count > 0 then - msg = S("Nearby nodes: @1", node_count) .. "\n " .. table.concat(found_nodes, ", ") - else - msg = S("No nearby nodes found.") - end - - return true, msg - end, -}) - - ---- Unsafe Commands. --- --- Enabled with [cleaner.unsafe](settings.html#cleaner.unsafe) setting. --- --- @section unsafe - - -if cleaner.unsafe then - --- Registers an ore to be removed. - -- - -- @chatcmd remove_ores - -- @param ore Ore technical name. - -- @priv server - -- @note This action is reverted after server restart. To make changes permanent, - -- use the [cleaner.json](config.html#cleaner.json) config. - -- @usage - -- # remove all registered ores that add default:stone_with_iron to world - -- /remove_ores default:stone_with_iron - core.register_chatcommand(cmd_repo.ore.cmd, { - privs = {server=true}, - description = S("Remove an ore from game.") .. "\n\n" - .. format_params(cmd_repo.ore.cmd), - params = cmd_repo.ore.help.param_string, - func = function(name, param) - local err - if not param or param:trim() == "" then - err = cmd_repo.param.missing - elseif param:find(" ") then - err = cmd_repo.param.excess - end - - if err then - return false, err .. "\n\n" .. format_help(cmd_repo.ore.cmd) - end - - 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 - - return success, msg - end - }) -end - ---- @section end - - ---- Manages settings for wielded [cleaner tool](tools.html). --- ---

Required Privileges:

--- --- - server --- --- @chatcmd ctool --- @param action Action to execute. Can be "status", "setmode", or "setnode". --- @param value Mode or node to be set for tool (not required for "status" action). --- @usage --- # while cleaner:pencil is wielded, configure to place default:dirt node when used --- /ctool setmode write --- /ctool setnode default:dirt -core.register_chatcommand(cmd_repo.tool.cmd, { - privs = {server=true}, - description = S("Manage settings for wielded cleaner tool.") .. "\n\n" - .. format_params(cmd_repo.tool.cmd), - params = cmd_repo.tool.help.param_string, - func = function(name, param) - local action, value = param - local idx = param:find(" ") - if idx then - param = string.split(param, " ") - action = param[1] - value = param[2] - end - - local help = format_help(cmd_repo.tool.cmd) - - local player = core.get_player_by_name(name) - local stack = player:get_wielded_item() - local iname = aux.tool:format_name(stack) - local imeta = stack:get_meta() - - if iname ~= "cleaner:pencil" then - return false, S("Unrecognized wielded item: @1", iname) .. "\n\n" .. help - end - - if action == "status" then - core.chat_send_player(name, iname .. ": " .. S("mode") .. "=" .. imeta:get_string("mode") - .. ", " .. S("node") .. "=" .. imeta:get_string("node")) - return true - end - - if not action or not value then - return false, S("Missing parameter.") .. "\n\n" .. help - end - - if action == "setmode" then - stack = aux.tool:set_mode(stack, value, name) - elseif action == "setnode" then - stack = aux.tool:set_node(stack, value, name) - else - return false, S("Unrecognized action: @1", action) .. "\n\n" .. help - end - - return player:set_wielded_item(stack) - end, -}) diff --git a/description.txt b/description.txt new file mode 100644 index 0000000..f04ad33 --- /dev/null +++ b/description.txt @@ -0,0 +1 @@ +A very simple mod that deletes unknown blocks and removes unknown entities. diff --git a/entities.lua b/entities.lua deleted file mode 100644 index 7b9da53..0000000 --- a/entities.lua +++ /dev/null @@ -1,59 +0,0 @@ - -local aux = dofile(cleaner.modpath .. "/misc_functions.lua") - --- populate entities list from file in world path -local entities_data = aux.get_world_data().entities - - --- START: backward compat - -local e_path = core.get_worldpath() .. "/clean_entities.json" -local e_file = io.open(e_path, "r") - -if e_file then - cleaner.log("action", "found deprecated clean_entities.json, updating") - - local data_in = core.parse_json(e_file:read("*a")) - e_file:close() - if data_in and data_in.remove then - for _, r in ipairs(data_in.remove) do - table.insert(entities_data.remove, r) - end - end - - -- don't read deprecated file again - os.rename(e_path, e_path .. ".old") -end - -local e_path_old = core.get_worldpath() .. "/clean_entities.txt" -e_file = io.open(e_path_old, "r") - -if e_file then - cleaner.log("action", "found deprecated clean_entities.txt, converting to json") - - local data_in = string.split(e_file:read("*a"), "\n") - for _, e in ipairs(data_in) do - e = e:trim() - if e ~= "" and e:sub(1, 1) ~= "#" then - table.insert(entities_data.remove, e) - end - end - - e_file:close() - os.rename(e_path_old, e_path_old .. ".bak") -- don't read deprecated file again -end - --- END: backward compat - - -entities_data.remove = aux.clean_duplicates(entities_data.remove) - --- update json file with any changes -aux.update_world_data("entities", entities_data) - -core.register_on_mods_loaded(function() - for _, e in ipairs(entities_data.remove) do - cleaner.log("action", "registering entity for removal: " .. e) - cleaner.register_entity_removal(e) - end -end) diff --git a/init.lua b/init.lua index 71d9ef2..bbdbca2 100644 --- a/init.lua +++ b/init.lua @@ -1,48 +1,43 @@ +-- clean by PilzAdam +-- LICENSE: WTFPL -cleaner = {} -cleaner.modname = core.get_current_modname() -cleaner.modpath = core.get_modpath(cleaner.modname) +local old_nodes = {} +local old_entities = {} -local cleaner_debug = core.settings:get_bool("enable_debug_mods", false) +-- Old/Missing nodes that should be replaced with something currently in game +local replace_nodes = {} -function cleaner.log(lvl, msg) - if lvl == "debug" and not cleaner_debug then return end - if lvl and not msg then - msg = lvl - lvl = nil - end - - msg = "[" .. cleaner.modname .. "] " .. msg - if lvl == "debug" then - msg = "[DEBUG] " .. msg - lvl = nil - end - - if not lvl then - core.log(msg) - else - core.log(lvl, msg) - end +-- "Replaces" an old/non-existent node +local function replace_node(old_node, new_node) + minetest.register_alias(old_node, new_node) end -local aux = dofile(cleaner.modpath .. "/misc_functions.lua") --- initialize world file -aux.update_world_data() - - -local scripts = { - "settings", - "api", - "chat", - "tools", - "entities", - "nodes", - "items", - "ores", -} - -for _, script in ipairs(scripts) do - dofile(cleaner.modpath .. "/" .. script .. ".lua") +for _,node_name in ipairs(old_nodes) do + minetest.register_node(':'..node_name, { + groups = {old=1}, + }) +end + +minetest.register_abm({ + nodenames = {'group:old'}, + interval = 1, + chance = 1, + action = function(pos, node) + minetest.remove_node(pos) + end, +}) + +for _,entity_name in ipairs(old_entities) do + minetest.register_entity(':'..entity_name, { + on_activate = function(self, staticdata) + self.object:remove() + end, + }) +end + +-- Replace old nodes +for _, node_group in pairs(replace_nodes) do + replace_node(node_group[1], node_group[2]) end diff --git a/items.lua b/items.lua deleted file mode 100644 index 02cde65..0000000 --- a/items.lua +++ /dev/null @@ -1,49 +0,0 @@ - -local aux = dofile(cleaner.modpath .. "/misc_functions.lua") - --- populate items list from file in world path -local items_data = aux.get_world_data().items - - --- START: backward compat - -local i_path = core.get_worldpath() .. "/clean_items.json" -local i_file = io.open(i_path, "r") - -if i_file then - cleaner.log("action", "found deprecated clean_items.json, updating") - - local data_in = core.parse_json(i_file:read("*a")) - i_file:close() - if data_in and data_in.replace then - for k, v in pairs(data_in.replace) do - if not items_data.replace[k] then - items_data.replace[k] = v - end - end - end - - -- don't read deprecated file again - os.rename(i_path, i_path .. ".old") -end - --- END: backward compat - - -aux.update_world_data("items", items_data) - -for i_old, i_new in pairs(items_data.replace) do - cleaner.register_item_replacement(i_old, i_new) -end - --- register actions for after server startup -core.register_on_mods_loaded(function() - for i_old, i_new in pairs(cleaner.get_replace_items()) do - cleaner.log("action", "registering item \"" .. i_old .. "\" to be replaced with \"" .. i_new .. "\"") - - local retval, msg = cleaner.replace_item(i_old, i_new) - if not retval then - cleaner.log("warning", msg) - end - end -end) diff --git a/locale/cleaner.es.tr b/locale/cleaner.es.tr deleted file mode 100644 index bbc0007..0000000 --- a/locale/cleaner.es.tr +++ /dev/null @@ -1,66 +0,0 @@ -# textdomain:cleaner - -# Translators: Jordan Irwin (AntumDeluge) - - -# chat commands -entity=entidad -mode=modo -node=nodo -radius=radio -old_item=objeto_antiguo -new_item=objeto_nuevo -old_node=nodo_antiguo -new_node=nodo_nuevo -ore=mineral -action=acción -value=valor -Usage:=Uso: -Params:=Parámetros: -default: @1=por defecto: @1 -Search radius.=Radio de búsqueda. -Entity technical name.=Nombre técnico de entidad. -Node technical name.=Nombre técnico de nodo. -Technical name of node to be replaced.=Nombre técnico del nodo reemplazado. -Technical name of node to be used in place.=Nombre técnico del nodo de reemplazo. -Technical name of item to be replaced.=Nombre técnico del objeto reemplazado. -Technical name of item to be used in place.=Nombre técnico del objeto de reemplazo. -Ore technical name.=Nombre técnico de mineral. -Action to execute. Can be one of "@1", "@2", or "@3".=La acción para ejecutar. Puede ser "@1", "@2", o "@3". -Mode or node to be set for tool (not required for "@1" action).=Modo o nodo para configurar a la herramienta (no se requiere para la acción de "@1"). -Remove an entity from game.=Eliminar una entidad del juego. -Remove a node from game.=Eliminar un nodo del juego. -Replace an item in game.=Sustituir un objecto del juego. -Replace a node in game.=Sustituir un nodo del juego. -Find names of unknown nodes.=Descubrir los nombres de nodos desconocidos. -Find names of nearby nodes.=Descubrir los nombres de nodos cercanos. -Remove an ore from game.=Eliminar un mineral del juego. -Missing parameter.=Parámetro extraviado. -Too many parameters.=Demasiados parámetros. -Radius must be a number.=El radio debe ser un número. -Cannot use unknown item "@1" as replacement.=El objeto "@1" es desonocido, no se puede utilizar como sustitución. -Cannot use unknown node "@1" as replacement.=El nodo "@1" es desonocido, no se puede utilizar como sustitución. -Replaced @1 nodes.=Nodos sustituidos: @1 -Removed @1 nodes.=Se eliminaron @1 nodos. -Removed @1 entities.=Se eliminaron @1 entidades. -Found unknown nodes: @1=Se encontraron @1 nodos desconocidos. -No unknown nodes found.=No se encontraron nodos desconocidos. -Nearby nodes: @1=Nodos cercanos: @1 -No nearby nodes found.=No se encontraron nodos cercanos. -Ore "@1" not found, not unregistering.=No se encontró el mineral "@1", se mantiene registrado. -Unregistered @1 ores (this will be undone after server restart).=Se anuló @1 minerales del registro. -Success!=¡Éxito! -Manage settings for wielded cleaner tool.=Administrar a los ajustes de la herramienta cleaner empuñada. -Unrecognized wielded item: @1=Objeto empuñado desconocido: @1 -Unrecognized action: @1=Acción desconocido: @1 -You do not have permission to set radius that high. Reduced to @1.=No tienes permiso para poner al radio tan alto. Se reduce a @1. -Radius is too high. Reduced to @1.=El radio es demasiado alto. Se reduce a @1. - -# tools: -@1: mode set to: @2=@1: modo configurado para: @2 -@1: node set to: @2=@1: nodo configurado para: @2 -Modes for tool "@1" not available.=Modos para herramienta "@1" no disponibles. -You do not have permission to use this item. Missing privs: @1=No tienes permiso para usar este objeto. Privs que faltan: @1 -Unknown mode: @1=Modo desconocido: @1 -Can't place node there.=No se puede poner nodo allí. -Cannot place unknown node: @1=No se puede poner nodo desconocido: @1 diff --git a/locale/template.txt b/locale/template.txt deleted file mode 100644 index 5373fb7..0000000 --- a/locale/template.txt +++ /dev/null @@ -1,66 +0,0 @@ -# textdomain:cleaner - -# Translators: - - -# chat commands -entity= -mode= -node= -radius= -old_item= -new_item= -old_node= -new_node= -ore= -action= -value= -Usage:= -Params:= -default: @1= -Search radius.= -Entity technical name.= -Node technical name.= -Technical name of node to be replaced.= -Technical name of node to be used in place.= -Technical name of item to be replaced.= -Technical name of item to be used in place.= -Ore technical name.= -Action to execute. Can be one of "@1", "@2", or "@3".= -Mode or node to be set for tool (not required for "@1" action).= -Remove an entity from game.= -Remove a node from game.= -Replace an item in game.= -Replace a node in game.= -Find names of unknown nodes.= -Find names of nearby nodes.= -Remove an ore from game.= -Missing parameter.= -Too many parameters.= -Radius must be a number.= -Cannot use unknown item "@1" as replacement.= -Cannot use unknown node "@1" as replacement.= -Replaced @1 nodes.= -Removed @1 nodes.= -Removed @1 entities.= -Found unknown nodes: @1= -No unknown nodes found.= -Nearby nodes: @1= -No nearby nodes found.= -Ore "@1" not found, not unregistering.= -Unregistered @1 ores (this will be undone after server restart).= -Success!= -Manage settings for wielded cleaner tool.= -Unrecognized wielded item: @1= -Unrecognized action: @1= -You do not have permission to set radius that high. Reduced to @1.= -Radius is too high. Reduced to @1.= - -# tools: -@1: mode set to: @2= -Modes for tool "@1" not available.= -@1: node set to: @2= -You do not have permission to use this item. Missing privs: @1= -Can't place node there.= -Unknown mode: @1= -Cannot place unknown node: @1= diff --git a/misc_functions.lua b/misc_functions.lua deleted file mode 100644 index 27c8654..0000000 --- a/misc_functions.lua +++ /dev/null @@ -1,258 +0,0 @@ - -local S = core.get_translator(cleaner.modname) - - ---- Cleans duplicate entries from indexed table. --- --- @local --- @function clean_duplicates --- @tparam table t --- @treturn table -local function clean_duplicates(t) - local tmp = {} - for _, v in ipairs(t) do - tmp[v] = true - end - - t = {} - for k in pairs(tmp) do - table.insert(t, k) - end - - return t -end - -local world_file = core.get_worldpath() .. "/cleaner.json" - -local function get_world_data() - local wdata = {} - local buffer = io.open(world_file, "r") - if buffer then - local err - wdata, err = core.parse_json(buffer:read("*a"), nil, true) - buffer:close() - if wdata == nil then - cleaner.log("warning", "reading world data file failed: " .. world_file) - wdata = {} - end - end - - local rem_types = {"entities", "nodes", "ores",} - local rep_types = {"items", "nodes",} - - for _, t in ipairs(rem_types) do - wdata[t] = wdata[t] or {} - wdata[t].remove = wdata[t].remove or {} - end - - for _, t in ipairs(rep_types) do - wdata[t] = wdata[t] or {} - wdata[t].replace = wdata[t].replace or {} - end - - return wdata -end - -local function update_world_data(t, data) - local wdata = get_world_data() - if t and data then - wdata[t].remove = data.remove - wdata[t].replace = data.replace - end - - local json_string = core.write_json(wdata, true):gsub("\"remove\" : null", "\"remove\" : []") - :gsub("\"replace\" : null", "\"replace\" : {}") - - local buffer = io.open(world_file, "w") - if buffer then - buffer:write(json_string) - buffer:close() - - return true - end - - return false -end - -local tool = { - modes = { - ["cleaner:pencil"] = {"erase", "write", "swap"}, - }, - - format_name = function(self, stack) - local iname = stack:get_name() - if iname == "cleaner:pencil_1" then - iname = "cleaner:pencil" - end - - return iname - end, - - set_mode = function(self, stack, mode, pname) - local iname = self:format_name(stack) - - if not self.modes[iname] then - if pname then - core.chat_send_player(pname, iname .. ": " .. S("unknown mode: @1", mode)) - end - cleaner.log("warning", iname .. ": unknown mode: " .. mode) - return stack - end - - local imeta = stack:get_meta() - imeta:set_string("mode", mode) - - if pname then - core.chat_send_player(pname, S("@1: mode set to: @2", iname, imeta:get_string("mode"))) - end - - local new_stack - if mode == "erase" then - new_stack = ItemStack("cleaner:pencil_1") - else - new_stack = ItemStack("cleaner:pencil") - end - - local new_meta = new_stack:get_meta() - new_meta:from_table(imeta:to_table()) - - return new_stack - end, - - next_mode = function(self, stack, pname) - local iname = self:format_name(stack) - local modes = self.modes[iname] - - if not modes then - return false, stack, S('Modes for tool "@1" not available.', stack:get_name()) - end - - local imeta = stack:get_meta() - local current_mode = imeta:get_string("mode") - if not current_mode or current_mode:trim() == "" then - return true, self:set_mode(stack, modes[1], pname) - end - - local idx = 1 - for _, m in ipairs(modes) do - if current_mode == m then - break - end - idx = idx + 1 - end - - return true, self:set_mode(stack, modes[idx+1] or modes[1], pname) - end, - - set_node = function(self, stack, node, pname) - local imeta = stack:get_meta() - imeta:set_string("node", node) - - if pname then - core.chat_send_player(pname, S("@1: node set to: @2", stack:get_name(), imeta:get_string("node"))) - end - - return stack - end, -} - -local use_sounds = core.global_exists("sounds") -local sound_handle - -tool.on_use = function(stack, user, pointed_thing) - if not user:is_player() then return end - - local pname = user:get_player_name() - if not core.get_player_privs(pname).server then - core.chat_send_player(pname, S("You do not have permission to use this item. Missing privs: @1", "server")) - return stack - end - - if sound_handle then - core.sound_stop(sound_handle) - sound_handle = nil - end - - if pointed_thing.type == "node" then - local npos = core.get_pointed_thing_position(pointed_thing) - local imeta = stack:get_meta() - local mode = imeta:get_string("mode") - local new_node_name = imeta:get_string("node") - - if mode == "erase" then - core.remove_node(npos) - if use_sounds then - local sound_handle = sounds.pencil_erase({object=user}) - end - return stack - elseif core.registered_nodes[new_node_name] then - if mode == "swap" then - core.swap_node(npos, {name=new_node_name}) - if use_sounds then - local sound_handle = sounds.pencil_write({object=user}) - end - elseif mode == "write" then - local node_above = core.get_node_or_nil(pointed_thing.above) - if not node_above or node_above.name == "air" then - core.set_node(pointed_thing.above, {name=new_node_name}) - if use_sounds then - local sound_handle = sounds.pencil_write({object=user}) - end - else - core.chat_send_player(pname, S("Can't place node there.")) - end - else - core.chat_send_player(pname, S("Unknown mode: @1", mode)) - end - - return stack - end - - core.chat_send_player(pname, S("Cannot place unknown node: @1", new_node_name)) - return stack - end -end - -tool.on_secondary_use = function(stack, user, pointed_thing) - if not user:is_player() then return end - - local pname = user:get_player_name() - if not core.get_player_privs(pname).server then - core.chat_send_player(pname, S("You do not have permission to use this item. Missing privs: @1", "server")) - return stack - end - - local success, stack, msg = tool.next_mode(tool, stack, pname) - if not success then - core.chat_send_player(pname, msg) - end - - return stack -end - -tool.on_place = function(stack, placer, pointed_thing) - if not placer:is_player() then return end - - local pname = placer:get_player_name() - if not core.get_player_privs(pname).server then - core.chat_send_player(pname, S("You do not have permission to use this item. Missing privs: @1", "server")) - return stack - end - - if pointed_thing.type == "node" then - local node = core.get_node_or_nil(core.get_pointed_thing_position(pointed_thing)) - if node then - stack = tool:set_node(stack, node.name, pname) - end - end - - return stack -end - - -return { - clean_duplicates = clean_duplicates, - get_world_data = get_world_data, - update_world_data = update_world_data, - tool = tool, -} diff --git a/mod.conf b/mod.conf index 03b84d4..a2e790c 100644 --- a/mod.conf +++ b/mod.conf @@ -1,7 +1,4 @@ -name = cleaner -description = A mod that can be used to remove/replace unknown entities, nodes, & items. -version = 2025-01-18 -license = MIT -author = PilzAdam, Jordan Irwin (AntumDeluge) -min_minetest_version = 5.0 -optional_depends = sounds +name = clean +author = PilzAdam +license = WTFPL +version = 0.1 diff --git a/nodes.lua b/nodes.lua deleted file mode 100644 index f3878ab..0000000 --- a/nodes.lua +++ /dev/null @@ -1,97 +0,0 @@ - -local aux = dofile(cleaner.modpath .. "/misc_functions.lua") - --- populate nodes list from file in world path -local nodes_data = aux.get_world_data().nodes - - --- START: backward compat - -local n_path = core.get_worldpath() .. "/clean_nodes.json" -local n_file = io.open(n_path, "r") - -if n_file then - cleaner.log("action", "found deprecated clean_nodes.json, updating") - - local data_in = core.parse_json(n_file:read("*a")) - n_file:close() - if data_in then - if data_in.remove then - for _, r in ipairs(data_in.remove) do - table.insert(nodes_data.remove, r) - end - end - - if data_in.replace then - for k, v in pairs(data_in.replace) do - if not nodes_data.replace[k] then - nodes_data.replace[k] = v - end - end - end - end - - -- don't read deprecated file again - os.rename(n_path, n_path .. ".old") -end - -local n_path_old = core.get_worldpath() .. "/clean_nodes.txt" -n_file = io.open(n_path_old, "r") - -if n_file then - cleaner.log("action", "found deprecated clean_nodes.txt, converting to json") - - local data_in = string.split(n_file:read("*a"), "\n") - for _, e in ipairs(data_in) do - e = e:trim() - if e ~= "" and e:sub(1, 1) ~= "#" then - table.insert(nodes_data.remove, e) - end - end - - n_file:close() - os.rename(n_path_old, n_path_old .. ".old") -- don't read deprecated file again -end - --- END: backward compat - - -nodes_data.remove = aux.clean_duplicates(nodes_data.remove) - --- update json file with any changes -aux.update_world_data("nodes", nodes_data) - -core.register_lbm({ - name = "cleaner:remove_nodes", - nodenames = {"group:to_remove"}, - run_at_every_load = true, - action = function(pos, node) - core.remove_node(pos) - end, -}) - -core.register_lbm({ - name = "cleaner:replace_nodes", - nodenames = {"group:to_replace"}, - run_at_every_load = true, - action = function(pos, node) - local new_node_name = cleaner.get_replace_nodes()[node.name] - if core.registered_nodes[new_node_name] then - core.swap_node(pos, {name=new_node_name}) - else - cleaner.log("error", "cannot replace with unregistered node \"" .. tostring(new_node_name) .. "\"") - end - end, -}) - -core.register_on_mods_loaded(function() - for _, n in ipairs(nodes_data.remove) do - cleaner.log("action", "registering node for removal: " .. n) - cleaner.register_node_removal(n) - end - - for n_old, n_new in pairs(nodes_data.replace) do - cleaner.log("action", "registering node \"" .. n_old .. "\" to be replaced with \"" .. n_new .. "\"") - cleaner.register_node_replacement(n_old, n_new) - end -end) diff --git a/ores.lua b/ores.lua deleted file mode 100644 index 517f60a..0000000 --- a/ores.lua +++ /dev/null @@ -1,17 +0,0 @@ - -if not cleaner.unsafe then return end - -local aux = dofile(cleaner.modpath .. "/misc_functions.lua") - -local ores_data = aux.get_world_data().ores - -for _, ore in ipairs(ores_data.remove) do - cleaner.register_ore_removal(ore) -end - -core.register_on_mods_loaded(function() - for _, ore in ipairs(cleaner.get_remove_ores()) do - cleaner.log("action", "unregistering ore: " .. ore) - cleaner.remove_ore(ore) - end -end) diff --git a/screenshot.png b/screenshot.png deleted file mode 100644 index 639655d..0000000 Binary files a/screenshot.png and /dev/null differ diff --git a/set_version.py b/set_version.py deleted file mode 100755 index 8c40217..0000000 --- a/set_version.py +++ /dev/null @@ -1,70 +0,0 @@ -#!/usr/bin/env python - -import sys, os, codecs - - -f_script = os.path.realpath(__file__) -d_root = os.path.dirname(f_script) - -os.chdir(d_root) - -args = sys.argv[1:] -if len(args) < 1: - print("ERROR: must supply version as parameter") - sys.exit(1) - -new_version = args[0] - -to_update = { - "mod.conf": "version =", - "changelog.txt": "next", - os.path.normpath(".ldoc/config.ld"): "local version =", -} - -for f in to_update: - f_path = os.path.join(d_root, f) - if not os.path.isfile(f_path): - print("WARNING: {} not found, skipping ...".format(f)) - continue - - print("\nsetting version to {} in {}".format(new_version, f_path)) - - buffer = codecs.open(f_path, "r", "utf-8") - if not buffer: - print("WARNING: could not open {} for reading, skipping ...".format(f)) - continue - - read_in = buffer.read() - buffer.close() - - read_in = read_in.replace("\r\n", "\n").replace("\r", "\n") - replacement = to_update[f] - new_lines = [] - - version_set = False - for li in read_in.split("\n"): - if not version_set: - if "=" in replacement and li.startswith(replacement): - key = li.split(" = ")[0] - li = "{} = {}".format(key, new_version) - version_set = True - elif li == replacement: - li = "v{}".format(new_version) - version_set = True - - new_lines.append(li) - - write_out = "\n".join(new_lines) - if write_out == read_in: - print("no changes for {}, skipping ...".format(f)) - continue - - buffer = codecs.open(f_path, "w", "utf-8") - if not buffer: - print("WARNING: could not open {} for writing, skipping ...".format(f)) - continue - - buffer.write("\n".join(new_lines)) - buffer.close() - - print("done") diff --git a/settings.lua b/settings.lua deleted file mode 100644 index 16c2f42..0000000 --- a/settings.lua +++ /dev/null @@ -1,15 +0,0 @@ - ---- Cleaner Settings --- --- @topic settings - - ---- Enables unsafe methods & chat commands. --- --- - `cleaner.remove_ore` --- - `/remove_ores` --- --- @setting cleaner.unsafe --- @settype bool --- @default false -cleaner.unsafe = core.settings:get_bool("cleaner.unsafe", false) diff --git a/settingtypes.txt b/settingtypes.txt deleted file mode 100644 index b5debc7..0000000 --- a/settingtypes.txt +++ /dev/null @@ -1,6 +0,0 @@ - -# Enables unsafe methods & chat commands. -# -# - cleaner.remove_ore -# - /remove_ores -cleaner.unsafe (Enable unsafe methods) bool false diff --git a/textures/cleaner_pencil.png b/textures/cleaner_pencil.png deleted file mode 100644 index 3582687..0000000 Binary files a/textures/cleaner_pencil.png and /dev/null differ diff --git a/tools.lua b/tools.lua deleted file mode 100644 index cc1c405..0000000 --- a/tools.lua +++ /dev/null @@ -1,44 +0,0 @@ - ---- Cleaner Tools --- --- @topic tools - - -local S = core.get_translator(cleaner.modname) - - -local aux = dofile(cleaner.modpath .. "/misc_functions.lua") - ---- Master Pencil --- --- @tool cleaner:pencil --- @img cleaner_pencil.png --- @priv server --- @usage --- place (right-click): --- - when not pointing at a node, changes modes --- - when pointing at a node, sets node to be used --- --- use (left-click): --- - executes action for current mode: --- - erase: erases pointed node --- - write: adds node --- - swap: replaces pointed node -core.register_tool(cleaner.modname .. ":pencil", { - description = S("Master Pencil"), - inventory_image = "cleaner_pencil.png", - liquids_pointable = true, - on_use = aux.tool.on_use, - on_secondary_use = aux.tool.on_secondary_use, - on_place = aux.tool.on_place, -}) - -core.register_tool(cleaner.modname .. ":pencil_1", { - description = S("Master Pencil"), - inventory_image = "cleaner_pencil.png^[transformFXFY", - liquids_pointable = true, - groups = {not_in_creative_inventory=1}, - on_use = aux.tool.on_use, - on_secondary_use = aux.tool.on_secondary_use, - on_place = aux.tool.on_place, -})