defripper-cd2025/commands.lua

170 lines
4.7 KiB
Lua
Raw Normal View History

-- LUALOCALS < ---------------------------------------------------------
local minetest, next, pairs, pcall, string, tonumber, vector
= minetest, next, pairs, pcall, string, tonumber, vector
2022-11-23 12:27:16 -05:00
local string_format, string_gsub, string_match
= string.format, string.gsub, string.match
-- LUALOCALS > ---------------------------------------------------------
local include = ...
local exportdb, savedb = include("exportdb")
local exportall = include("exportall")
local modname = minetest.get_current_modname()
local function save_export_report()
savedb()
local defs, media = exportall()
return true, string_format("exported %d defs and %d media", defs, media)
end
minetest.register_chatcommand(modname, {
description = "Rip all items in already marked for export",
privs = {server = true},
func = save_export_report
})
minetest.register_chatcommand(modname .. "_clear", {
description = "Clear all saved exports",
privs = {server = true},
func = function()
for k in pairs(exportdb) do exportdb[k] = nil end
return save_export_report()
end
})
minetest.register_chatcommand(modname .. "_inv", {
description = "Rip all items in inventory",
privs = {server = true},
func = function(name)
local player = minetest.get_player_by_name(name)
if not player then return false, "invalid player" end
for _, list in pairs(player:get_inventory():get_lists()) do
for _, stack in pairs(list) do
if not stack:is_empty() then
exportdb[stack:get_name()] = true
end
end
end
return save_export_report()
end
})
2022-11-23 12:27:16 -05:00
local function patternfunc(setto)
return function(_, param)
if param == "" then return false, "must supply pattern" end
local ok, err = pcall(function()
for k in pairs(minetest.registered_items) do
if string_match(k, param) then
exportdb[k] = setto
end
end
end)
if not ok then return false, string_gsub(err, ".*:%d+:%s*", "") end
return save_export_report()
end
end
minetest.register_chatcommand(modname .. "_add", {
description = "Rip all defs with technical names matching a pattern",
params = "<lua pattern>",
privs = {server = true},
func = patternfunc(true)
})
minetest.register_chatcommand(modname .. "_rm", {
description = "Un-rip all defs with technical names matching a pattern",
params = "<lua pattern>",
privs = {server = true},
func = patternfunc(nil)
})
local function ripradius(pos, radius)
local foundids = {}
do
local vm = minetest.get_voxel_manip(
vector.subtract(pos, radius),
vector.add(pos, radius))
local data = vm:get_data()
for i = 1, #data do foundids[data[i]] = true end
end
local dirty
for k in pairs(foundids) do
local n = minetest.get_name_from_content_id(k)
if n and not exportdb[n] then
exportdb[n] = true
dirty = true
end
end
return dirty
end
minetest.register_chatcommand(modname .. "_here", {
description = "Rip all nodes within a radius",
params = "[radius_x=100 [radius_y=radius_x [radius_z=radius_x]]]",
privs = {server = true},
func = function(name, param)
local player = minetest.get_player_by_name(name)
if not player then return false, "invalid player" end
local parts = param:split(" ")
local rx = parts[1] and tonumber(parts[1]) or 100
local ry = parts[2] and tonumber(parts[2]) or rx
local rz = parts[3] and tonumber(parts[3]) or rx
ripradius(player:get_pos(), vector.new(rx, ry, rz))
return save_export_report()
end
})
local steprippers = {}
local stepripstart
do
local pended
local function stepriprun()
pended = false
if next(steprippers) == nil then return end
for pname, pdata in pairs(steprippers) do
local player = minetest.get_player_by_name(pname)
if player then
local pos = player:get_pos()
local oldpos = pdata.pos
if (not oldpos) or (vector.distance(pos, oldpos) >= pdata.step) then
pdata.pos = pos
if ripradius(pos, pdata.radius) then
minetest.chat_send_player(pname, "exporting...")
local _, rpt = save_export_report()
minetest.chat_send_player(pname, rpt)
end
end
end
end
return stepripstart()
end
stepripstart = function()
if pended then return end
minetest.after(0, stepriprun)
pended = true
end
end
minetest.register_chatcommand(modname .. "_step", {
description = "Rip nodes in radius every step",
params = "[radius_x=100 [radius_y=radius_x [radius_z=radius_x [stepsize=2]]]]",
privs = {server = true},
func = function(name, param)
local parts = param:split(" ")
local rx = parts[1] and tonumber(parts[1]) or 100
local ry = parts[2] and tonumber(parts[2]) or rx
local rz = parts[3] and tonumber(parts[3]) or rx
steprippers[name] = rx > 0 and {
radius = vector.new(rx, ry, rz),
step = parts[4] and tonumber(parts[4]) or 2
} or nil
stepripstart()
end
})